-
Notifications
You must be signed in to change notification settings - Fork 66
Harden CI: bind verify-published-wheel's dispatch input to env #5744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fb5143d
1c0a7ee
7167ae3
c43b045
ac6e8c9
aa22cb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -73,16 +73,43 @@ jobs: | |
| - name: Resolve version | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PR implements the blueprint's template injection hardening pattern (env binding, regex validation before GITHUB_OUTPUT, explicit shell:bash), but the WorkflowIntegrityGuard component's documented responsibilities do not include checking for workflow_dispatch template injection patterns, contradicting the blueprint's assertion that the guard covers this pattern. |
||
| id: ver | ||
| shell: python | ||
| # The dispatch input is bound here rather than expanded inside the | ||
| # script. A `${{ }}` expansion is pasted into the program text before | ||
| # the interpreter runs, so the value becomes part of the program; an | ||
| # env var is data the program only ever reads. This step is the taint | ||
| # root for the whole job -- the verify step below reads | ||
| # `steps.ver.outputs.version`, which is this value. | ||
| # | ||
| # The rule is recorded, not just applied: "A workflow input is data, | ||
| # never program text" in the Release Verification and Merge Gating | ||
| # blueprint. #5673 fixed this same construct in auto-deploy-cloud.yml | ||
| # and it recurred here, because nothing wrote the rule down and nothing | ||
| # failed when it came back. WorkflowIntegrityGuard now covers the | ||
| # pattern, so a third occurrence fails a check instead of waiting for a | ||
| # reviewer to recognise the shape. | ||
| env: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PR hardens verify-published-wheel.yml against template injection by binding workflow_dispatch inputs to env variables and validating them before they reach GITHUB_OUTPUT—a security pattern not documented in the WorkflowIntegrityGuard component that scans workflows for script injection. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PR implements template injection hardening in verify-published-wheel.yml by binding workflow_dispatch inputs to env variables and validating them before GITHUB_OUTPUT, but the WorkflowIntegrityGuard component doesn't document checking for this security pattern in dispatch input handling. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PR implements template injection hardening for workflow_dispatch inputs (binding to env, validating before GITHUB_OUTPUT, explicit shell:bash), but the WorkflowIntegrityGuard component is not documented as checking for this security pattern in workflow definitions, despite its stated responsibility to scan workflows for script injection. |
||
| INPUT_VERSION: ${{ github.event.inputs.version }} | ||
| run: | | ||
| import json, os, urllib.request | ||
| want = "${{ github.event.inputs.version }}".strip() | ||
| import json, os, re, urllib.request | ||
| want = os.environ.get("INPUT_VERSION", "").strip() | ||
| if not want: | ||
| with urllib.request.urlopen( | ||
| "https://pypi.org/pypi/clawmetry/json", timeout=30) as r: | ||
| want = json.load(r)["info"]["version"] | ||
| # Belt to the env-binding's braces: what goes into GITHUB_OUTPUT is a | ||
| # bare version and nothing else, so a later step cannot inherit a | ||
| # newline (which would forge a second output) or shell metacharacters. | ||
| if not re.fullmatch(r"[0-9A-Za-z.+!-]{1,64}", want): | ||
| raise SystemExit(f"not a version string, refusing to continue: {want!r}") | ||
| with open(os.environ["GITHUB_OUTPUT"], "a") as fh: | ||
| fh.write(f"version={want}\n") | ||
| print(f"verifying clawmetry=={want}") | ||
|
|
||
| # `shell: bash` is explicit because this runs on the Windows leg too, | ||
| # where the default shell is pwsh and `$VERSION` would silently read as | ||
| # an unset PowerShell variable rather than the environment variable. | ||
| - name: Verify the published wheel | ||
| run: python scripts/verify_published_wheel.py --version "${{ steps.ver.outputs.version }}" | ||
| shell: bash | ||
| env: | ||
| VERSION: ${{ steps.ver.outputs.version }} | ||
| run: python scripts/verify_published_wheel.py --version "$VERSION" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR implements template injection hardening for workflow_dispatch inputs (binding to env, regex validation before GITHUB_OUTPUT), but the blueprint's WorkflowIntegrityGuard component does not document checking for this security pattern in workflow dispatch input handling despite the SecurityAuditScanner component mentioning script injection scanning.