You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cache poisoning and `pull_request_target` abuse become much more impactful when the **release workflow publishes through OIDC trusted publishing** instead of a static registry token:
522
+
523
+
1. A low-trust workflow (`pull_request_target`, `issue_comment`, bot command, etc.) writes a **malicious binary/script** into a cache key later restored by the privileged release workflow.
524
+
2. The release job restores and executes that binary while holding **`id-token: write`** or an already-minted registry session.
525
+
3. The attacker steals the short-lived identity material, usually by either:
526
+
- directly requesting a GitHub OIDC token from `ACTIONS_ID_TOKEN_REQUEST_URL` with `ACTIONS_ID_TOKEN_REQUEST_TOKEN`, or
527
+
- dumping the runner worker process memory / tool-specific token cache after the publish helper requested the token.
528
+
4. The stolen OIDC token is exchanged with the registry trusted-publishing / federation endpoint for **real publish credentials**, so the malicious package is published by the victim's own CI/CD pipeline.
529
+
530
+
This is important because **npm provenance and Sigstore attestations only prove that the package was produced by the expected build workflow**. They do **not** prove that the workflow was free from attacker-controlled code. If the attacker compromises the trusted builder itself, the backdoored package can still receive valid provenance.
531
+
532
+
Practical implications during an assessment:
533
+
534
+
- Look for release jobs with **`permissions: id-token: write`** plus `npm publish`, `pnpm publish`, `changesets`, or custom publish wrappers.
535
+
- Treat `ACTIONS_ID_TOKEN_REQUEST_URL`, `ACTIONS_ID_TOKEN_REQUEST_TOKEN`, runner memory, and CLI token caches as **equivalent credential sources** once code execution is obtained in the release context.
536
+
- Do not assume `npm audit signatures` / provenance verification will detect a package built by a **compromised but legitimate** workflow.
537
+
538
+
**Mitigations**
539
+
540
+
- Keep untrusted workflows and release workflows on **separate cache namespaces** and never restore executable tooling from a cache written by PR-triggerable jobs.
541
+
- Minimize `id-token: write` to the exact publish step/job and avoid exposing OIDC-capable helpers earlier in the workflow.
542
+
- Rebuild/rehash restored binaries or download them from a verified source before execution; do not execute toolchains directly from cache paths.
543
+
- Treat provenance as an **origin signal**, not a standalone safety signal; combine it with workflow hardening, dependency diffing, and runtime validation.
544
+
519
545
### Artifact Poisoning
520
546
521
547
Workflows could use **artifacts from other workflows and even repos**, if an attacker manages to **compromise** the Github Action that **uploads an artifact** that is later used by another workflow he could **compromise the other workflows**:
@@ -910,5 +936,9 @@ An organization in GitHub is very proactive in reporting accounts to GitHub. All
- [A Survey of 2024–2025 Open-Source Supply-Chain Compromises and Their Root Causes](https://words.filippo.io/compromise-survey/)
912
938
- [Weaponizing the Protectors: TeamPCP’s Multi-Stage Supply Chain Attack on Security Infrastructure](https://unit42.paloaltonetworks.com/teampcp-supply-chain-attacks/)
939
+
- [Mini Shai-Hulud: Frequently asked questions about the TeamPCP npm and PyPI supply chain campaign](https://www.tenable.com/blog/mini-shai-hulud-frequently-asked-questions)
940
+
- [Events that trigger workflows - GitHub Docs](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows)
941
+
- [Trusted publishing for npm packages | npm Docs](https://docs.npmjs.com/trusted-publishers/)
0 commit comments