Triggers on a privileged event — pull_request_target or workflow_run, and
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.
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.
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.
--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.
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.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Pipefort","description":"Scan GitHub Actions workflows for the OWASP Top 10 CI/CD risks — via CLI or a multi-tenant web dashboard.","colors":{"primary":"#6366f1","light":"#818cf8","dark":"#7c3aed"},"logo":{"light":"https://mintcdn.com/pipefort/olYtgDhS-tmc12H3/logo/light.svg?fit=max\u0026auto=format\u0026n=olYtgDhS-tmc12H3\u0026q=85\u0026s=0603d0920c0fb24833a95cd83cf82214","dark":"https://mintcdn.com/pipefort/olYtgDhS-tmc12H3/logo/dark.svg?fit=max\u0026auto=format\u0026n=olYtgDhS-tmc12H3\u0026q=85\u0026s=5b20cdc0cf52696bd7860083a3dcc547"},"favicon":"https://mintcdn.com/pipefort/olYtgDhS-tmc12H3/shield.svg?fit=max\u0026auto=format\u0026n=olYtgDhS-tmc12H3\u0026q=85\u0026s=50ddd6ec7558eaa1b12d8b79780d371e","appearance":{"default":"dark","strict":true},"navbar":{"primary":{"type":"button","label":"Get started","href":"/quickstart"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"pipefort","hasAudioNarration":false,"actualSubdomain":"pipefort","customDomains":["docs.pipefort.com"],"gitSource":{"type":"github","owner":"raphabot","repo":"pipefort-cloud","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6a9f73638d98389808c4e557","clientVersion":"0.0.4087","searchFilterCounts":[{"language":"default","tag":"Documentation","count":121},{"language":"default","tag":"Rules reference","count":83},{"language":"default","tag":"Web app","count":23},{"language":"default","tag":"CLI","count":9},{"language":"default","tag":"Get started","count":4},{"language":"default","tag":"Concepts","count":1},{"language":"default","tag":"Editor","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"rules/cicd-sec-1","slug":"/rules/cicd-sec-1","pageMetadata":{"title":"CICD-SEC-1 — Dangerous pull_request_target checkout","description":"Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.","href":"/rules/cicd-sec-1"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Field`}),_jsx(_components.th,{children:`Value`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Category`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`CICD-SEC-1`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Severity`}),_jsx(_components.td,{children:_jsx(_components.strong,{children:`HIGH`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`OWASP`}),_jsx(_components.td,{children:_jsx(_components.a,{href:`https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-01-Insufficient-Flow-Control-Mechanisms`,children:`CICD-SEC-1: Insufficient Flow Control`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Auto-fix`}),_jsxs(_components.td,{children:[`✓ (`,_jsx(_components.a,{href:`#auto-fix`,children:`what it does`}),`)`]})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`what-the-check-does`,children:`What the check does`}),`\n`,_jsx(_components.p,{children:`Flags any workflow that:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Triggers on a `,_jsx(_components.strong,{children:`privileged event`}),` — `,_jsx(_components.code,{children:`pull_request_target`}),` or `,_jsx(_components.code,{children:`workflow_run`}),`, `,_jsx(_components.strong,{children:`and`})]}),`\n`,_jsxs(_components.li,{children:[`Uses `,_jsx(_components.code,{children:`actions/checkout`}),` with `,_jsx(_components.code,{children:`ref:`}),` referencing the untrusted head: `,_jsx(_components.code,{children:`github.event.pull_request.head`}),`, `,_jsx(_components.code,{children:`github.head_ref`}),`, `,_jsx(_components.code,{children:`refs/pull/…`}),`, or `,_jsx(_components.code,{children:`github.event.workflow_run.head…`}),`.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The trigger detection handles all three forms of `,_jsx(_components.code,{children:`on:`}),` — scalar, sequence, and mapping.`]}),`\n`,_jsx(Heading,{level:`2`,id:`why-it’s-dangerous`,children:`Why it’s dangerous`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`pull_request_target`}),` and `,_jsx(_components.code,{children:`workflow_run`}),` run in the context of the `,_jsx(_components.strong,{children:`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.`]}),`\n`,_jsx(Heading,{level:`2`,id:`vulnerable-example`,children:`Vulnerable example`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`10`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`name`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`ci`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`on`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`pull_request_target`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`jobs`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` test`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` runs-on`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`ubuntu-latest`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` steps`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`uses`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`actions/checkout@v4`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` with`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` ref`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"${{ github.event.pull_request.head.sha }}\"}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # ← untrusted code`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`run`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`npm test`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # ← runs with secrets`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`safe-alternatives`,children:`Safe alternatives`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Use the standard `,_jsx(_components.code,{children:`pull_request`}),` trigger instead. It runs in the PR’s `,_jsx(_components.em,{children:`own`}),` context and doesn’t expose secrets.`]}),`\n`,_jsxs(_components.li,{children:[`If you must use `,_jsx(_components.code,{children:`pull_request_target`}),` (e.g. to label PRs from forks), don’t check out the head ref — operate only on metadata.`]}),`\n`,_jsxs(_components.li,{children:[`For workflows that `,_jsx(_components.em,{children:`need`}),` to run user code against secrets (rare), gate the job on `,_jsx(_components.code,{children:`if: github.event.pull_request.head.repo.full_name == github.repository`}),` so it skips forks.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`auto-fix`,children:`Auto-fix`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`--fix`}),` rewrites the trigger from `,_jsx(_components.code,{children:`pull_request_target`}),` to `,_jsx(_components.code,{children:`pull_request`}),`. It handles scalar, sequence, and mapping forms. If `,_jsx(_components.code,{children:`pull_request`}),` is already in the trigger list, the `,_jsx(_components.code,{children:`pull_request_target`}),` entry is removed. Findings from the `,_jsx(_components.code,{children:`workflow_run`}),` variant are flag-only — switching that trigger isn’t a safe mechanical rewrite, so they require manual remediation.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`The auto-fix changes the trigger but does `,_jsx(_components.strong,{children:`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.`]})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"CICD-SEC-1 — Dangerous pull_request_target checkout","description":"Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.","href":"/rules/cicd-sec-1"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"What the check does","slug":"what-the-check-does","depth":2,"children":[]},{"title":"Why it’s dangerous","slug":"why-it’s-dangerous","depth":2,"children":[]},{"title":"Vulnerable example","slug":"vulnerable-example","depth":2,"children":[]},{"title":"Safe alternatives","slug":"safe-alternatives","depth":2,"children":[]},{"title":"Auto-fix","slug":"auto-fix","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"pipefort","siteName":"Pipefort","title":"CICD-SEC-1 — Dangerous pull_request_target checkout - Pipefort","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-06-10T18:04:13.238Z","originalFileLocation":"rules/cicd-sec-1.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=\"dark\";if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Pipefort\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"CICD-SEC-1 — Dangerous pull_request_target checkout - Pipefort\">\u003cmeta data-mint-head property=\"og:description\" content=\"Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Pipefort\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.pipefort.com/rules/cicd-sec-1\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://pipefort.mintlify.site/_mintlify/api/og/v2?division=Rules+reference\u0026amp;title=CICD-SEC-1+%E2%80%94+Dangerous+pull_request_target+checkout\u0026amp;description=Checking+out+untrusted+PR+head+code+in+a+pull_request_target+workflow+exposes+repository+secrets.\u0026amp;theme=0e4b43e2e988d8c2899aac73\u0026amp;signature=9559bdea167e4c312e4d87273698d93aeda9e42d9a9c9111366b40a277cfd619\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"CICD-SEC-1 — Dangerous pull_request_target checkout - Pipefort\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://pipefort.mintlify.site/_mintlify/api/og/v2?division=Rules+reference\u0026amp;title=CICD-SEC-1+%E2%80%94+Dangerous+pull_request_target+checkout\u0026amp;description=Checking+out+untrusted+PR+head+code+in+a+pull_request_target+workflow+exposes+repository+secrets.\u0026amp;theme=0e4b43e2e988d8c2899aac73\u0026amp;signature=9559bdea167e4c312e4d87273698d93aeda9e42d9a9c9111366b40a277cfd619\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/pipefort/nYTI7MrvpVVY_Rzg/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Pipefort\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#6366f1\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.pipefort.com/rules/cicd-sec-1\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/rules/cicd-sec-1.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.pipefort.com/#organization\",\"name\":\"Pipefort\",\"url\":\"https://docs.pipefort.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/pipefort/olYtgDhS-tmc12H3/logo/light.svg?fit=max\u0026auto=format\u0026n=olYtgDhS-tmc12H3\u0026q=85\u0026s=0603d0920c0fb24833a95cd83cf82214\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.pipefort.com#website\",\"name\":\"Pipefort\",\"url\":\"https://docs.pipefort.com\",\"publisher\":{\"@id\":\"https://docs.pipefort.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.pipefort.com/rules/cicd-sec-1#webpage\",\"url\":\"https://docs.pipefort.com/rules/cicd-sec-1\",\"name\":\"CICD-SEC-1 — Dangerous pull_request_target checkout\",\"description\":\"Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.\",\"dateModified\":\"2026-06-10T18:04:13.238Z\",\"isPartOf\":{\"@id\":\"https://docs.pipefort.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.pipefort.com/rules/cicd-sec-1#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.pipefort.com/rules/cicd-sec-1#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Rules reference\",\"item\":\"https://docs.pipefort.com/rules/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CICD-SEC-1 — Dangerous pull_request_target checkout\",\"item\":\"https://docs.pipefort.com/rules/cicd-sec-1\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.pipefort.com/rules/cicd-sec-1#article\",\"headline\":\"CICD-SEC-1 — Dangerous pull_request_target checkout\",\"name\":\"CICD-SEC-1 — Dangerous pull_request_target checkout\",\"description\":\"Checking out untrusted PR head code in a pull_request_target workflow exposes repository secrets.\",\"url\":\"https://docs.pipefort.com/rules/cicd-sec-1\",\"mainEntityOfPage\":{\"@id\":\"https://docs.pipefort.com/rules/cicd-sec-1#webpage\"},\"dateModified\":\"2026-06-10T18:04:13.238Z\",\"publisher\":{\"@id\":\"https://docs.pipefort.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.pipefort.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Pipefort\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Pipefort","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Get started","pages":[{"title":"Introduction","href":"/introduction"},{"title":"Quickstart","href":"/quickstart"},{"title":"How it works","href":"/architecture"},{"title":"How Pipefort compares","href":"/comparison"}]},{"group":"CLI","pages":[{"title":"Overview","href":"/cli/overview"},{"title":"Installation","href":"/cli/installation"},{"title":"Usage","href":"/cli/usage"},{"title":"Flags","href":"/cli/flags"},{"title":"Auto-fix","href":"/cli/auto-fix"},{"title":"Configuration file","href":"/cli/configuration"},{"title":"MCP server","href":"/cli/mcp"},{"title":"GitLab CLI usage","href":"/cli/gitlab"},{"title":"CI integration","href":"/cli/ci-integration"}]},{"group":"Editor","pages":[{"title":"VS Code extension","href":"/editor/vscode"}]},{"group":"Web app","pages":[{"title":"Overview","href":"/webapp/overview"},{"title":"Public repo scanner","href":"/webapp/public-scan"},{"title":"Status badge","href":"/webapp/badge"},{"title":"Organizations","href":"/webapp/organizations"},{"title":"GitHub setup","href":"/webapp/github-setup"},{"title":"Monitored repos","href":"/webapp/monitored-repos"},{"title":"Pull request checks","href":"/webapp/pr-checks"},{"title":"Finding triage \u0026 new findings","href":"/webapp/finding-triage"},{"title":"Action risk scores","href":"/webapp/action-risk-scores"},{"title":"Secure Workflow Hardener","href":"/webapp/workflow-hardener"},{"title":"Actions inventory","href":"/webapp/actions-inventory"},{"title":"Secrets hygiene","href":"/webapp/secrets-hygiene"},{"title":"Bulk remediation campaigns","href":"/webapp/bulk-remediation"},{"title":"Notifications","href":"/webapp/notifications"},{"title":"SLSA dashboard","href":"/webapp/slsa"},{"title":"Attacker Mind dashboard","href":"/webapp/attacker-mind"},{"title":"Insights","href":"/webapp/insights"},{"title":"Rule policy","href":"/webapp/rule-settings"},{"title":"Alert rules","href":"/webapp/alert-rules"},{"title":"API tokens","href":"/webapp/api-tokens"},{"title":"Audit log","href":"/webapp/audit-log"},{"title":"API reference","href":"/webapp/api-reference"},{"title":"Agent discovery","href":"/webapp/agent-discovery"}]},{"group":"Concepts","pages":[{"title":"Github app permissions","href":"/concepts/github-app-permissions"},{"title":"Attacker Mind \u0026 toxic combinations","href":"/concepts/attacker-mind"}]},{"group":"Rules reference","pages":[{"title":"Rules overview","href":"/rules/overview"},{"title":"SLSA framework overview","description":"Pipefort's SLSA v1.2 Build- and Source-track coverage, control by control.","href":"/rules/slsa-overview"},{"title":"CICD-SEC-1 — Dangerous pull_request_target checkout","href":"/rules/cicd-sec-1"},{"title":"CICD-SEC-1 — workflow_run downloads artifacts from the triggering run","description":"A workflow_run workflow downloads and trusts artifacts produced by the untrusted run that triggered it.","href":"/rules/cicd-sec-1-workflow-run-artifact-poisoning"},{"title":"CICD-SEC-1 — Checkout persists credentials under a privileged trigger","href":"/rules/cicd-sec-1-checkout-persist-credentials"},{"title":"CICD-SEC-1 — Security decision based on a spoofable actor check","href":"/rules/cicd-sec-1-spoofable-actor-condition"},{"title":"CICD-SEC-1 — Job/step condition is always true","href":"/rules/cicd-sec-1-unsound-condition"},{"title":"CICD-SEC-1 — Spoofable contains() membership check","href":"/rules/cicd-sec-1-unsound-contains"},{"title":"CICD-SEC-1 — pull_request_target trigger boundary confusion","href":"/rules/cicd-sec-1-pr-target-dual-trigger"},{"title":"CICD-SEC-1 — Unsafe YAML tag or multiplying anchor expansion","href":"/rules/cicd-sec-1-yaml-parser-hardening"},{"title":"CICD-SEC-2 — Long-lived personal access token in workflow","href":"/rules/cicd-sec-2"},{"title":"CICD-SEC-2 — Package published with a long-lived token instead of OIDC","href":"/rules/cicd-sec-2-use-trusted-publishing"},{"title":"CICD-SEC-2 — Static cloud credential where OIDC federation is available","href":"/rules/cicd-sec-2-cloud-credentials"},{"title":"CICD-SEC-3 — Unpinned third-party action","href":"/rules/cicd-sec-3"},{"title":"CICD-SEC-3 — Unpinned container image","href":"/rules/cicd-sec-3-unpinned-image"},{"title":"CICD-SEC-3 — Known-vulnerable action version","href":"/rules/cicd-sec-3-known-vulnerable-action"},{"title":"CICD-SEC-3 — Impostor commit pin","href":"/rules/cicd-sec-3-impostor-commit"},{"title":"CICD-SEC-3 — Pinned SHA does not match its version comment","href":"/rules/cicd-sec-3-ref-version-mismatch"},{"title":"CICD-SEC-3 — Possible typosquatted action","href":"/rules/cicd-sec-3-typosquat-action"},{"title":"CICD-SEC-3 — Action's upstream repository is archived","href":"/rules/cicd-sec-3-archived-action"},{"title":"CICD-SEC-3 — Pinned SHA is not any released tag","href":"/rules/cicd-sec-3-stale-action-ref"},{"title":"CICD-SEC-3 — Action ref exists as both a branch and a tag","href":"/rules/cicd-sec-3-ref-confusion"},{"title":"CICD-SEC-4 — Poisoned Pipeline Execution (shell injection)","href":"/rules/cicd-sec-4"},{"title":"CICD-SEC-4 — Untrusted input written to GITHUB_ENV/GITHUB_PATH","href":"/rules/cicd-sec-4-github-env-injection"},{"title":"CICD-SEC-4 — Reusable workflow called with secrets: inherit under a privileged trigger","href":"/rules/cicd-sec-4-secrets-inherit-pr-target"},{"title":"CICD-SEC-4 — Obfuscated expression or run script","href":"/rules/cicd-sec-4-obfuscated-expression"},{"title":"CICD-SEC-4 — Caching enabled in a publishing workflow","href":"/rules/cicd-sec-4-cache-poisoning-release"},{"title":"CICD-SEC-5 — Missing permissions specification","href":"/rules/cicd-sec-5"},{"title":"CICD-SEC-5 — Action not permitted by forbidden-uses policy","href":"/rules/cicd-sec-5-forbidden-uses"},{"title":"CICD-SEC-6 — Hardcoded credentials","href":"/rules/cicd-sec-6"},{"title":"CICD-SEC-6 — Secret printed to logs or written to step output","href":"/rules/cicd-sec-6-secret-in-run-output"},{"title":"CICD-SEC-6 — Secrets over-provisioned to the whole workflow","href":"/rules/cicd-sec-6-overprovisioned-secrets"},{"title":"CICD-SEC-6 — Run step dumps the environment or echoes a CI token","href":"/rules/cicd-sec-6-env-exfil"},{"title":"CICD-SEC-7 — Actions debug logging enabled in workflow","href":"/rules/cicd-sec-7"},{"title":"CICD-SEC-7 — Build artifact published without a retention cap","href":"/rules/cicd-sec-7-artifact-exposure"},{"title":"CICD-SEC-8 — repository_dispatch trigger without event-type allowlist","href":"/rules/cicd-sec-8"},{"title":"CICD-SEC-8 — Sensitive job on a self-hosted runner with no declared egress restriction","href":"/rules/cicd-sec-8-selfhosted-egress"},{"title":"CICD-SEC-9 — Downloaded artifact has no integrity check","href":"/rules/cicd-sec-9"},{"title":"CICD-SEC-10 — Job-level continue-on-error suppresses failure visibility","href":"/rules/cicd-sec-10"},{"title":"BEST-PRAC-1 — Command piped directly to shell","href":"/rules/best-prac-1"},{"title":"BEST-PRAC-2 — Job timeout not configured","href":"/rules/best-prac-2"},{"title":"BEST-PRAC-3 — Self-hosted runner usage","href":"/rules/best-prac-3"},{"title":"BEST-PRAC-4 — Deploy/release workflow has no concurrency guard","href":"/rules/best-prac-4-missing-concurrency"},{"title":"BEST-PRAC-5 — Multi-command shell step runs without strict mode","href":"/rules/best-prac-5-shell-hardening"},{"title":"SLSA-BUILD-L2 — Build provenance is not generated","href":"/rules/slsa-build-l2-provenance"},{"title":"SLSA-BUILD-L2 — Provenance/signing step is missing id-token: write","href":"/rules/slsa-build-l2-oidc-token-scope"},{"title":"SLSA-BUILD-L2 — Permissions block grants overly broad scopes","href":"/rules/slsa-build-l2-perms-overly-broad"},{"title":"SLSA-BUILD-L2 — Workflow consumes artifacts but does not verify provenance","href":"/rules/slsa-build-l2-verify-step"},{"title":"SLSA-BUILD-L3 — Provenance is generated in-job, not isolated","href":"/rules/slsa-build-l3-provenance-isolated"},{"title":"SLSA-BUILD-L3 — Cache key in pull_request_target derived from PR input","href":"/rules/slsa-build-l3-cache-poisoning"},{"title":"CICD-SEC-1 — Default branch has no branch protection rule","href":"/rules/cicd-sec-1-bp-missing"},{"title":"CICD-SEC-1 — Default branch allows force pushes","href":"/rules/cicd-sec-1-bp-force-push"},{"title":"CICD-SEC-1 — Default branch can be deleted","href":"/rules/cicd-sec-1-bp-deletion"},{"title":"CICD-SEC-1 — Default branch does not require pull request reviews","href":"/rules/cicd-sec-1-bp-no-review"},{"title":"CICD-SEC-1 — Default branch requires fewer than 2 approving reviews","href":"/rules/cicd-sec-1-bp-few-reviewers"},{"title":"CICD-SEC-1 — Default branch does not dismiss stale reviews on new commits","href":"/rules/cicd-sec-1-bp-stale-reviews"},{"title":"CICD-SEC-1 — Default branch does not require status checks to pass","href":"/rules/cicd-sec-1-bp-no-status-checks"},{"title":"CICD-SEC-1 — Admins can bypass branch protection","href":"/rules/cicd-sec-1-bp-admin-bypass"},{"title":"CICD-SEC-1 — CODEOWNERS exists but their review is not required","href":"/rules/cicd-sec-1-bp-no-codeowners-review"},{"title":"CICD-SEC-1 — Default branch does not require signed commits","href":"/rules/cicd-sec-1-bp-no-signed-commits"},{"title":"CICD-SEC-4 — Default GITHUB_TOKEN permissions are read-write","href":"/rules/cicd-sec-4-wperm-write"},{"title":"CICD-SEC-4 — GitHub Actions can approve pull requests","href":"/rules/cicd-sec-4-wperm-pr-approve"},{"title":"CICD-SEC-5 — All GitHub Actions and reusable workflows are allowed","href":"/rules/cicd-sec-5-actions-all-allowed"},{"title":"CICD-SEC-3 — Dependabot alerts are disabled","href":"/rules/cicd-sec-3-dependabot-alerts-off"},{"title":"CICD-SEC-3 — Dependabot security updates are disabled","href":"/rules/cicd-sec-3-dependabot-fixes-off"},{"title":"CICD-SEC-6 — Secret scanning is disabled","href":"/rules/cicd-sec-6-secret-scanning-off"},{"title":"CICD-SEC-6 — Secret-scanning push protection is disabled","href":"/rules/cicd-sec-6-secret-push-protection-off"},{"title":"CICD-SEC-1 (GitLab) — Pipeline runs untrusted merge-request code with protected secrets","href":"/rules/cicd-sec-1-gl-mr-target"},{"title":"CICD-SEC-2 (GitLab) — Long-lived access token used instead of CI_JOB_TOKEN","href":"/rules/cicd-sec-2-gl-pat-secret"},{"title":"CICD-SEC-3 (GitLab) — Unpinned remote include","href":"/rules/cicd-sec-3-gl-unpinned-include"},{"title":"CICD-SEC-4 (GitLab) — Shell injection from pipeline variables","href":"/rules/cicd-sec-4-gl-shell-injection"},{"title":"CICD-SEC-6 (GitLab) — Hardcoded secret in pipeline config","href":"/rules/cicd-sec-6-gl-hardcoded-secrets"},{"title":"CICD-SEC-7 (GitLab) — Debug tracing enabled","href":"/rules/cicd-sec-7-gl-debug-trace"},{"title":"CICD-SEC-8 (GitLab) — Trigger/pipeline job without source filtering","href":"/rules/cicd-sec-8-gl-trigger-unfiltered"},{"title":"CICD-SEC-10 (GitLab) — allow_failure hides job failures","href":"/rules/cicd-sec-10-gl-allow-failure"},{"title":"BEST-PRAC-2 (GitLab) — Job has no timeout","href":"/rules/best-prac-2-gl-missing-timeout"},{"title":"BEST-PRAC-3 (GitLab) — Job targets a self-hosted runner","href":"/rules/best-prac-3-gl-self-hosted-tags"},{"title":"BEST-PRAC-4 (GitLab) — Deploy job has no resource_group","href":"/rules/best-prac-4-gl-missing-resource-group"},{"title":"CICD-SEC-1 (GitLab) — Default branch is not protected","href":"/rules/cicd-sec-1-gl-bp-missing"},{"title":"CICD-SEC-1 (GitLab) — Protected default branch allows force push","href":"/rules/cicd-sec-1-gl-bp-force-push"},{"title":"CICD-SEC-1 (GitLab) — Merges allowed without a passing pipeline","href":"/rules/cicd-sec-1-gl-merge-without-pipeline"},{"title":"CICD-SEC-1 (GitLab) — Merge requests require no approvals","href":"/rules/cicd-sec-1-gl-no-approvals"},{"title":"CICD-SEC-4 (GitLab) — Public pipelines expose job logs and artifacts","href":"/rules/cicd-sec-4-gl-public-pipelines"}]}]}]},"basePath":"","title":"CICD-SEC-1 — Dangerous pull_request_target checkout - Pipefort","buildId":"dpl_FWZhTb2vab28gFGFH4ojka6qEznQ","deploymentId":"dpl_FWZhTb2vab28gFGFH4ojka6qEznQ","dynamics":[],"chunks":[]}