Skip to main content

What the check does

Fires only on workflows triggered by workflow_run. Within those, it flags any step that downloads artifacts produced by the triggering run:
  • uses: actions/download-artifact (any version)
  • uses: dawidd6/action-download-artifact
  • an inline run: containing gh run download

Why it matters

The workflow_run event runs in the base repository’s privileged context — with repository secrets and a token — after another workflow (often the fork-PR pull_request build) completes. Artifacts uploaded by that first workflow are attacker-controlled: a fork PR can put anything in them. If the workflow_run workflow downloads those artifacts and then executes them, unzips them over the workspace, or echoes their contents into a privileged step, the attacker achieves code execution or content injection with secrets in scope. This is the “artifact poisoning” half of the classic pull_requestworkflow_run escalation.

Vulnerable example

Safe alternatives

  • Treat downloaded artifacts as untrusted data: validate their shape and contents before use, and never execute them or feed them into a step holding secrets.
  • Prefer reading the PR metadata you actually need from the workflow_run event payload rather than round-tripping it through an artifact.
  • If you only need to post a comment or status, do the privileged action with values you control, not values read from the artifact.