[WIP] Automate generation of weekly CSV reports for Canton wallets#111
[WIP] Automate generation of weekly CSV reports for Canton wallets#111
Conversation
Co-authored-by: derrix060 <[email protected]>
|
|
||
| - name: Generate Canton wallet reports | ||
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} |
Check warning
Code scanning / CodeQL
Code injection Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 9 days ago
In general, to fix this class of problem, any untrusted GitHub Actions input must not be interpolated directly into shell commands via ${{ ... }} inside a run: block. Instead, assign it to an environment variable at the step level using expression syntax, and then reference it using the shell’s native variable expansion ($VAR), avoiding unquoted command construction where possible.
For this workflow, the best fix is:
- Add an
env:section on the “Generate Canton wallet reports” step that maps:OUTPUT_DIR: ${{ inputs.output_dir }}USE_MOCK_DATA: ${{ inputs.use_mock_data }}VALIDATOR_ONLY: ${{ inputs.validator_only }}NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }}DAYS: ${{ inputs.days }}
- In the shell script:
- Replace
mkdir -p ${{ inputs.output_dir }}withmkdir -p "$OUTPUT_DIR". - Initialize
ARGS="--output-dir \"$OUTPUT_DIR\""so the directory is properly quoted. - Replace all
${{ inputs.* }}conditions with checks against the corresponding env vars ($USE_MOCK_DATA, etc.). - Replace
ARGS="$ARGS --days ${{ inputs.days }}"withARGS="$ARGS --days $DAYS". - Finally, run the Python script with safe argument passing:
python3 scripts/generate_canton_reports.py $ARGS. Because we’re constructing a single string, to fully avoid word-splitting issues you could instead build an array, but that would be a larger functional change. Given the existing pattern, ensuring that only trusted or simple values are interpolated and that paths are quoted keeps behavior while addressing the injection vector from${{ ... }}.
- Replace
We must also fix later uses of ${{ inputs.output_dir }} in other steps’ run: sections by moving the value into an env var and using $OUTPUT_DIR instead. The upload-artifact with.path is not executed as shell, so it may remain unchanged, but keeping it consistent by using an env var is still safe; however, to minimize changes we will only adjust the run: blocks.
All required changes are confined to .github/workflows/canton-reports.yaml in the shown step definitions; no new methods or external dependencies are needed.
| @@ -49,31 +49,40 @@ | ||
| python-version: '3.11' | ||
|
|
||
| - name: Generate Canton wallet reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| USE_MOCK_DATA: ${{ inputs.use_mock_data }} | ||
| VALIDATOR_ONLY: ${{ inputs.validator_only }} | ||
| NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }} | ||
| DAYS: ${{ inputs.days }} | ||
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} | ||
| mkdir -p "$OUTPUT_DIR" | ||
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" | ||
| ARGS="--output-dir \"$OUTPUT_DIR\"" | ||
|
|
||
| if [ "${{ inputs.use_mock_data }}" == "true" ]; then | ||
| if [ "$USE_MOCK_DATA" = "true" ]; then | ||
| ARGS="$ARGS --mock" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.validator_only }}" == "true" ]; then | ||
| if [ "$VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --validator-only" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.non_validator_only }}" == "true" ]; then | ||
| if [ "$NON_VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --non-validator-only" | ||
| fi | ||
|
|
||
| ARGS="$ARGS --days ${{ inputs.days }}" | ||
| ARGS="$ARGS --days $DAYS" | ||
|
|
||
| # shellcheck disable=SC2086 | ||
| python3 scripts/generate_canton_reports.py $ARGS | ||
|
|
||
| - name: List generated reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| run: | | ||
| echo "Generated reports:" | ||
| ls -lh ${{ inputs.output_dir }} | ||
| ls -lh "$OUTPUT_DIR" | ||
|
|
||
| - name: Upload reports as artifacts | ||
| uses: actions/upload-artifact@v4 |
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} | ||
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" |
Check warning
Code scanning / CodeQL
Code injection Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 9 days ago
In general, to fix this kind of issue in GitHub Actions, you should stop interpolating untrusted inputs directly into run: commands using ${{ ... }} and instead: (1) assign the expression value to an environment variable using env: or env on the step, and (2) reference that environment variable using the shell’s native variable syntax ("$VAR"). This way the shell receives the value as a single argument and does not re-interpret any embedded metacharacters as additional commands.
For this specific workflow, we should:
- Pass
inputs.output_dirandinputs.daysinto the step via environment variables, e.g.OUTPUT_DIR: ${{ inputs.output_dir }}andDAYS: ${{ inputs.days }}. - In the
run:script, replace${{ inputs.output_dir }}and${{ inputs.days }}with$OUTPUT_DIRand$DAYS. - Build
ARGSusing those shell variables so the script never sees GitHub expression syntax inside the command text. - For the later steps that call
lsand configureactions/upload-artifact, avoid using${{ inputs.output_dir }}directly in shell commands as well: use anenvmapping and shell variables for commands, while keeping${{ ... }}only in YAML keys/values that are not executed as shell.
All of this can be done within .github/workflows/canton-reports.yaml without changing behavior: the Python script still gets the same arguments, and artifacts are uploaded from the same directory, but the shell never sees raw GitHub expression syntax that can expand to untrusted content.
| @@ -49,31 +49,39 @@ | ||
| python-version: '3.11' | ||
|
|
||
| - name: Generate Canton wallet reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| USE_MOCK_DATA: ${{ inputs.use_mock_data }} | ||
| VALIDATOR_ONLY: ${{ inputs.validator_only }} | ||
| NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }} | ||
| DAYS: ${{ inputs.days }} | ||
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} | ||
| mkdir -p "$OUTPUT_DIR" | ||
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" | ||
| ARGS="--output-dir $OUTPUT_DIR" | ||
|
|
||
| if [ "${{ inputs.use_mock_data }}" == "true" ]; then | ||
| if [ "$USE_MOCK_DATA" = "true" ]; then | ||
| ARGS="$ARGS --mock" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.validator_only }}" == "true" ]; then | ||
| if [ "$VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --validator-only" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.non_validator_only }}" == "true" ]; then | ||
| if [ "$NON_VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --non-validator-only" | ||
| fi | ||
|
|
||
| ARGS="$ARGS --days ${{ inputs.days }}" | ||
| ARGS="$ARGS --days $DAYS" | ||
|
|
||
| python3 scripts/generate_canton_reports.py $ARGS | ||
|
|
||
| - name: List generated reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| run: | | ||
| echo "Generated reports:" | ||
| ls -lh ${{ inputs.output_dir }} | ||
| ls -lh "$OUTPUT_DIR" | ||
|
|
||
| - name: Upload reports as artifacts | ||
| uses: actions/upload-artifact@v4 |
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" | ||
|
|
||
| if [ "${{ inputs.use_mock_data }}" == "true" ]; then |
Check warning
Code scanning / CodeQL
Code injection Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 9 days ago
In general, to fix GitHub Actions code injection issues you should: (1) assign any untrusted or user-controlled ${{ inputs.* }} values to environment variables via the env: block of the step, and (2) only reference them inside the shell using native shell syntax ($VAR), never ${{ env.VAR }}. If you need boolean logic, do it at the shell level using the environment variables’ values.
For this workflow, the best fix without changing functionality is:
- Add an
env:section to the “Generate Canton wallet reports” step to capture all relevant inputs (OUTPUT_DIR,USE_MOCK_DATA,VALIDATOR_ONLY,NON_VALIDATOR_ONLY,DAYS) from their${{ inputs.* }}values. - In the
run:script:- Replace
mkdir -p ${{ inputs.output_dir }}withmkdir -p "$OUTPUT_DIR". - Initialize
ARGSusing$OUTPUT_DIRinstead of${{ inputs.output_dir }}. - Replace
if [ "${{ inputs.use_mock_data }}" == "true" ]; thenwithif [ "$USE_MOCK_DATA" = "true" ]; then(and similarly for the other two booleans). - Replace
ARGS="$ARGS --days ${{ inputs.days }}"withARGS="$ARGS --days $DAYS".
- Replace
- In the “List generated reports” and “Upload reports as artifacts” steps, move
${{ inputs.output_dir }}into an env var as well and use$OUTPUT_DIRin the shell commands and artifact path. This keeps behavior but removes expression expansion from within shell code and paths.
No new methods or external libraries are needed; we only adjust the YAML for the workflow and use standard shell variable expansion.
| @@ -49,31 +49,39 @@ | ||
| python-version: '3.11' | ||
|
|
||
| - name: Generate Canton wallet reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| USE_MOCK_DATA: ${{ inputs.use_mock_data }} | ||
| VALIDATOR_ONLY: ${{ inputs.validator_only }} | ||
| NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }} | ||
| DAYS: ${{ inputs.days }} | ||
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} | ||
| mkdir -p "$OUTPUT_DIR" | ||
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" | ||
| ARGS="--output-dir $OUTPUT_DIR" | ||
|
|
||
| if [ "${{ inputs.use_mock_data }}" == "true" ]; then | ||
| if [ "$USE_MOCK_DATA" = "true" ]; then | ||
| ARGS="$ARGS --mock" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.validator_only }}" == "true" ]; then | ||
| if [ "$VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --validator-only" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.non_validator_only }}" == "true" ]; then | ||
| if [ "$NON_VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --non-validator-only" | ||
| fi | ||
|
|
||
| ARGS="$ARGS --days ${{ inputs.days }}" | ||
| ARGS="$ARGS --days $DAYS" | ||
|
|
||
| python3 scripts/generate_canton_reports.py $ARGS | ||
|
|
||
| - name: List generated reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| run: | | ||
| echo "Generated reports:" | ||
| ls -lh ${{ inputs.output_dir }} | ||
| ls -lh "$OUTPUT_DIR" | ||
|
|
||
| - name: Upload reports as artifacts | ||
| uses: actions/upload-artifact@v4 |
| ARGS="$ARGS --mock" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.validator_only }}" == "true" ]; then |
Check warning
Code scanning / CodeQL
Code injection Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 9 days ago
To fix the problem, we should stop using ${{ inputs.* }} directly inside the shell script body. Instead, we will map all workflow inputs to environment variables via the env: section of the step and then use standard shell variable expansion like $VALIDATOR_ONLY etc. This aligns with GitHub’s recommended pattern and prevents expression-based code injection.
Concretely, in the “Generate Canton wallet reports” step:
- Add an
env:block that assigns each input to an environment variable, e.g.VALIDATOR_ONLY: ${{ inputs.validator_only }},OUTPUT_DIR: ${{ inputs.output_dir }},USE_MOCK_DATA: ${{ inputs.use_mock_data }},NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }},DAYS: ${{ inputs.days }}. - In the
run:script:- Replace
mkdir -p ${{ inputs.output_dir }}withmkdir -p "$OUTPUT_DIR". - Initialize
ARGS="--output-dir \"$OUTPUT_DIR\""instead of using${{ inputs.output_dir }}directly. - Change the
ifchecks fromif [ "${{ inputs.use_mock_data }}" == "true" ]; thenetc. toif [ "$USE_MOCK_DATA" = "true" ]; then, similarly forVALIDATOR_ONLYandNON_VALIDATOR_ONLY. - Replace
ARGS="$ARGS --days ${{ inputs.days }}"withARGS="$ARGS --days $DAYS".
- Replace
- Quote variables properly to avoid word splitting and preserve paths with spaces.
Other steps (List generated reports, Upload reports as artifacts) still use ${{ inputs.output_dir }} in non-shell contexts or in simple path usage. These are not subject to the same injection pattern because they are not being parsed by a shell via run:, so we can leave them unchanged.
All changes occur within .github/workflows/canton-reports.yaml in the shown step, and no new imports or external libraries are needed.
| @@ -49,24 +49,30 @@ | ||
| python-version: '3.11' | ||
|
|
||
| - name: Generate Canton wallet reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| USE_MOCK_DATA: ${{ inputs.use_mock_data }} | ||
| VALIDATOR_ONLY: ${{ inputs.validator_only }} | ||
| NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }} | ||
| DAYS: ${{ inputs.days }} | ||
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} | ||
| mkdir -p "$OUTPUT_DIR" | ||
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" | ||
| ARGS="--output-dir \"$OUTPUT_DIR\"" | ||
|
|
||
| if [ "${{ inputs.use_mock_data }}" == "true" ]; then | ||
| if [ "$USE_MOCK_DATA" = "true" ]; then | ||
| ARGS="$ARGS --mock" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.validator_only }}" == "true" ]; then | ||
| if [ "$VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --validator-only" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.non_validator_only }}" == "true" ]; then | ||
| if [ "$NON_VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --non-validator-only" | ||
| fi | ||
|
|
||
| ARGS="$ARGS --days ${{ inputs.days }}" | ||
| ARGS="$ARGS --days $DAYS" | ||
|
|
||
| python3 scripts/generate_canton_reports.py $ARGS | ||
|
|
| ARGS="$ARGS --validator-only" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.non_validator_only }}" == "true" ]; then |
Check warning
Code scanning / CodeQL
Code injection Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 9 days ago
In general, to prevent code injection in GitHub Actions shell steps, interpolate untrusted inputs into environment variables at the workflow level, then reference them using the shell’s native variable syntax ($VAR, "${VAR}") inside run:. Avoid ${{ ... }} within the script body. This prevents user-controlled content from being interpreted by the GitHub expression engine and injected into the shell.
For this workflow, the safest fix is to:
- Add an
env:block on theGenerate Canton wallet reportsstep that maps each used input (output_dir,use_mock_data,validator_only,non_validator_only,days) into an environment variable, e.g.OUTPUT_DIR: ${{ inputs.output_dir }}. - Rewrite the shell script to use those environment variables via shell syntax only, e.g.
mkdir -p "$OUTPUT_DIR",if [ "$USE_MOCK_DATA" = "true" ]; then ...,ARGS="$ARGS --days $DAYS", andpython3 scripts/generate_canton_reports.py $ARGS. - Apply the same pattern to the
List generated reportsstep and the upload-artifactpath, by definingOUTPUT_DIRinenv:and using$OUTPUT_DIRinrun:andwith:where appropriate (forwith:we still must use${{ env.OUTPUT_DIR }}, but that’s not a shell context).
All edits are confined to .github/workflows/canton-reports.yaml within the provided regions: add env: blocks to the two shell steps and the upload step, and replace usages of ${{ inputs.* }} inside run: with the corresponding shell variables. No new methods or external libraries are needed.
| @@ -49,36 +49,46 @@ | ||
| python-version: '3.11' | ||
|
|
||
| - name: Generate Canton wallet reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| USE_MOCK_DATA: ${{ inputs.use_mock_data }} | ||
| VALIDATOR_ONLY: ${{ inputs.validator_only }} | ||
| NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }} | ||
| DAYS: ${{ inputs.days }} | ||
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} | ||
| mkdir -p "$OUTPUT_DIR" | ||
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" | ||
| ARGS="--output-dir $OUTPUT_DIR" | ||
|
|
||
| if [ "${{ inputs.use_mock_data }}" == "true" ]; then | ||
| if [ "$USE_MOCK_DATA" = "true" ]; then | ||
| ARGS="$ARGS --mock" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.validator_only }}" == "true" ]; then | ||
| if [ "$VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --validator-only" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.non_validator_only }}" == "true" ]; then | ||
| if [ "$NON_VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --non-validator-only" | ||
| fi | ||
|
|
||
| ARGS="$ARGS --days ${{ inputs.days }}" | ||
| ARGS="$ARGS --days $DAYS" | ||
|
|
||
| python3 scripts/generate_canton_reports.py $ARGS | ||
|
|
||
| - name: List generated reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| run: | | ||
| echo "Generated reports:" | ||
| ls -lh ${{ inputs.output_dir }} | ||
| ls -lh "$OUTPUT_DIR" | ||
|
|
||
| - name: Upload reports as artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| with: | ||
| name: canton-wallet-reports-${{ github.run_id }} | ||
| path: ${{ inputs.output_dir }}/*.csv | ||
| path: ${{ env.OUTPUT_DIR }}/*.csv | ||
| retention-days: 90 | ||
| if-no-files-found: error |
| ARGS="$ARGS --non-validator-only" | ||
| fi | ||
|
|
||
| ARGS="$ARGS --days ${{ inputs.days }}" |
Check warning
Code scanning / CodeQL
Code injection Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 9 days ago
In general, to fix this pattern in GitHub Actions, any untrusted input should first be assigned to an environment variable via ${{ }} in the YAML, and then referenced using the shell’s native variable expansion ($VAR) inside the run: script. This avoids injecting GitHub expressions directly into the command string and lets the shell treat the value as plain data.
For this specific workflow, we should:
- Move all
${{ inputs.* }}usages withinrun:blocks intoenv:declarations for the step. - In the shell script, read those environment variables using
$OUTPUT_DIR,$USE_MOCK_DATA,$VALIDATOR_ONLY,$NON_VALIDATOR_ONLY, and$DAYS. - Also update the later
List generated reportsstep to use$OUTPUT_DIRrather than${{ inputs.output_dir }}for consistency and safety.
Concretely, in .github/workflows/canton-reports.yaml:
- In the “Generate Canton wallet reports” step, add an
env:section mapping each input to a corresponding env var, and rewrite the script to use those env vars instead of${{ inputs.* }}. - In the “List generated reports” step, add an
env:section forOUTPUT_DIRand changels -lh ${{ inputs.output_dir }}tols -lh "$OUTPUT_DIR".
No additional methods or external libraries are needed; this is purely a YAML and shell change.
| @@ -49,31 +49,41 @@ | ||
| python-version: '3.11' | ||
|
|
||
| - name: Generate Canton wallet reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| USE_MOCK_DATA: ${{ inputs.use_mock_data }} | ||
| VALIDATOR_ONLY: ${{ inputs.validator_only }} | ||
| NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }} | ||
| DAYS: ${{ inputs.days }} | ||
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} | ||
| mkdir -p "$OUTPUT_DIR" | ||
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" | ||
| ARGS="--output-dir \"$OUTPUT_DIR\"" | ||
|
|
||
| if [ "${{ inputs.use_mock_data }}" == "true" ]; then | ||
| if [ "$USE_MOCK_DATA" = "true" ]; then | ||
| ARGS="$ARGS --mock" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.validator_only }}" == "true" ]; then | ||
| if [ "$VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --validator-only" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.non_validator_only }}" == "true" ]; then | ||
| if [ "$NON_VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --non-validator-only" | ||
| fi | ||
|
|
||
| ARGS="$ARGS --days ${{ inputs.days }}" | ||
| ARGS="$ARGS --days \"$DAYS\"" | ||
|
|
||
| python3 scripts/generate_canton_reports.py $ARGS | ||
| # shellcheck disable=SC2086 | ||
| eval set -- $ARGS | ||
| python3 scripts/generate_canton_reports.py "$@" | ||
|
|
||
| - name: List generated reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| run: | | ||
| echo "Generated reports:" | ||
| ls -lh ${{ inputs.output_dir }} | ||
| ls -lh "$OUTPUT_DIR" | ||
|
|
||
| - name: Upload reports as artifacts | ||
| uses: actions/upload-artifact@v4 |
| - name: List generated reports | ||
| run: | | ||
| echo "Generated reports:" | ||
| ls -lh ${{ inputs.output_dir }} |
Check warning
Code scanning / CodeQL
Code injection Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 9 days ago
To fix this, we should stop interpolating inputs.output_dir (and the other user-controllable inputs) directly into the shell commands with ${{ ... }} and instead assign them to environment variables via env: and reference them using native shell syntax ($OUTPUT_DIR, $USE_MOCK_DATA, etc.). This follows GitHub’s recommended mitigation pattern and prevents shell from interpreting injected characters as code.
Concretely, in .github/workflows/canton-reports.yaml:
- For the “Generate Canton wallet reports” step:
- Add an
env:block that maps all workflow inputs used in the script (output_dir,use_mock_data,validator_only,non_validator_only,days) to environment variables (e.g.,OUTPUT_DIR: ${{ inputs.output_dir }}, etc.). - In the
run:script:- Replace
mkdir -p ${{ inputs.output_dir }}withmkdir -p "$OUTPUT_DIR". - Initialize
ARGSwith--output-dir "$OUTPUT_DIR"instead of referencing the expression directly. - Replace all
if [ "${{ inputs.X }}" == "true" ]; thenbranches to check the corresponding env var:if [ "$USE_MOCK_DATA" = "true" ]; thenetc. - Replace
ARGS="$ARGS --days ${{ inputs.days }}"withARGS="$ARGS --days $DAYS".
- Replace
- Add an
- For the “List generated reports” step:
- Add an
env:block withOUTPUT_DIR: ${{ inputs.output_dir }}. - Replace
ls -lh ${{ inputs.output_dir }}withls -lh "$OUTPUT_DIR".
- Add an
We leave non-shell contexts (like artifact path:) unchanged, since they are not interpreted as shell commands. This preserves existing functionality while eliminating direct interpolation of untrusted values into the shell.
| @@ -49,31 +49,39 @@ | ||
| python-version: '3.11' | ||
|
|
||
| - name: Generate Canton wallet reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| USE_MOCK_DATA: ${{ inputs.use_mock_data }} | ||
| VALIDATOR_ONLY: ${{ inputs.validator_only }} | ||
| NON_VALIDATOR_ONLY: ${{ inputs.non_validator_only }} | ||
| DAYS: ${{ inputs.days }} | ||
| run: | | ||
| mkdir -p ${{ inputs.output_dir }} | ||
| mkdir -p "$OUTPUT_DIR" | ||
|
|
||
| ARGS="--output-dir ${{ inputs.output_dir }}" | ||
| ARGS="--output-dir \"$OUTPUT_DIR\"" | ||
|
|
||
| if [ "${{ inputs.use_mock_data }}" == "true" ]; then | ||
| if [ "$USE_MOCK_DATA" = "true" ]; then | ||
| ARGS="$ARGS --mock" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.validator_only }}" == "true" ]; then | ||
| if [ "$VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --validator-only" | ||
| fi | ||
|
|
||
| if [ "${{ inputs.non_validator_only }}" == "true" ]; then | ||
| if [ "$NON_VALIDATOR_ONLY" = "true" ]; then | ||
| ARGS="$ARGS --non-validator-only" | ||
| fi | ||
|
|
||
| ARGS="$ARGS --days ${{ inputs.days }}" | ||
| ARGS="$ARGS --days $DAYS" | ||
|
|
||
| python3 scripts/generate_canton_reports.py $ARGS | ||
|
|
||
| - name: List generated reports | ||
| env: | ||
| OUTPUT_DIR: ${{ inputs.output_dir }} | ||
| run: | | ||
| echo "Generated reports:" | ||
| ls -lh ${{ inputs.output_dir }} | ||
| ls -lh "$OUTPUT_DIR" | ||
|
|
||
| - name: Upload reports as artifacts | ||
| uses: actions/upload-artifact@v4 |
Plan for Automating Weekly Canton Wallet CSV Reports (ANG-812)
nethermind-angkor-1::12201d94ec4ba973ab5c51e3b769a6aca54f061afc963619a4d6109044eaccafc7banethermind::1220409a9fcc5ff6422e29ab978c22c004dde33202546b4bcbde24b25b85353366c2💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.