> ## 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 — Dangerous pull_request_target checkout

> Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.

| Field    | Value                                                                                                                                               |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Category | `CICD-SEC-1`                                                                                                                                        |
| Severity | **HIGH**                                                                                                                                            |
| OWASP    | [CICD-SEC-1: Insufficient Flow Control](https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-01-Insufficient-Flow-Control-Mechanisms) |
| Auto-fix | ✓ ([what it does](#auto-fix))                                                                                                                       |

## What the check does

Flags any workflow that:

1. Triggers on a **privileged event** — `pull_request_target` or `workflow_run`, **and**
2. Uses `actions/checkout` with `ref:` referencing the untrusted head: `github.event.pull_request.head`, `github.head_ref`, `refs/pull/…`, or `github.event.workflow_run.head…`.

The trigger detection handles all three forms of `on:` — scalar, sequence, and mapping.

## Why it's dangerous

`pull_request_target` and `workflow_run` run in the context of the **base branch** with repository secrets and write permissions. If you then check out the PR's head ref and run tests, builds, or any user-controlled script, an attacker who opens a PR can execute arbitrary code with elevated privileges and exfiltrate secrets.

## Vulnerable example

```yaml theme={null}
name: ci
on: pull_request_target
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}   # ← untrusted code
      - run: npm test                                       # ← runs with secrets
```

## Safe alternatives

* Use the standard `pull_request` trigger instead. It runs in the PR's *own* context and doesn't expose secrets.
* If you must use `pull_request_target` (e.g. to label PRs from forks), don't check out the head ref — operate only on metadata.
* For workflows that *need* to run user code against secrets (rare), gate the job on `if: github.event.pull_request.head.repo.full_name == github.repository` so it skips forks.

## Auto-fix

`--fix` rewrites the trigger from `pull_request_target` to `pull_request`. It handles scalar, sequence, and mapping forms. If `pull_request` is already in the trigger list, the `pull_request_target` entry is removed. Findings from the `workflow_run` variant are flag-only — switching that trigger isn't a safe mechanical rewrite, so they require manual remediation.

<Warning>
  The auto-fix changes the trigger but does **not** remove the checkout-of-head step — the underlying code is no longer dangerous because the workflow now runs in the PR's context, but review the diff to confirm the change matches your intent.
</Warning>
