> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pipefort.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CICD-SEC-1 — workflow_run downloads artifacts from the triggering run

> A workflow_run workflow downloads and trusts artifacts produced by the untrusted run that triggered it.

| Field    | Value                                                                                                                                                          |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Category | `CICD-SEC-1`                                                                                                                                                   |
| Rule ID  | `cicd-sec-1-workflow-run-artifact-poisoning`                                                                                                                   |
| Severity | **HIGH**                                                                                                                                                       |
| OWASP    | [CICD-SEC-1: Insufficient Flow Control Mechanisms](https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-01-Insufficient-Flow-Control-Mechanisms) |
| Auto-fix | ✗                                                                                                                                                              |

## 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_request` → `workflow_run` escalation.

## Vulnerable example

```yaml theme={null}
on:
  workflow_run:
    workflows: [CI]
    types: [completed]
jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4   # artifact came from the untrusted PR build
      - run: ./scripts/$(cat ./artifact/name) # executes attacker-chosen content
```

## 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.
