Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,43 @@ import base64,os;exec(base64.b64decode(os.environ["STAGE2_B64"]))

Drop the line above into a file such as `evil.pth` inside `site-packages` and it will execute during Python startup. This is especially useful in build agents that continuously spawn Python tooling (`pip`, linters, test runners, release scripts).

#### `binding.gyp` / node-gyp execution (`Phantom Gyp`)

Not every install-time execution path lives in `package.json` lifecycle hooks. `node-gyp`'s `configure` step looks for a `binding.gyp` file in the package directory, so a compromised publisher can shift execution into the native build path and bypass controls that only audit `preinstall` / `postinstall`.

Practical implications during an assessment:

- Inspect the **published tarball**, not only the Git repo, for unexpected `binding.gyp`, `node-gyp`, or native-addon metadata in packages that should be pure JavaScript.
- Treat a sudden `binding.gyp` addition as an **execution primitive**, especially if defenders rely on lifecycle-hook monitoring or `--ignore-scripts` as their main intake control.
- Review release jobs that run `npm install`, `npm rebuild`, or other dependency build steps after restoring untrusted artifacts/caches, because a poisoned package can move execution to the native-build path.

#### Wormable npm publishing from CI / stolen maintainer identities

Once code runs in a maintainer workstation or release workflow, a single stolen registry identity can be turned into **self-propagating package compromise**:

1. Harvest maintainer secrets (`~/.npmrc`, PATs, OIDC request env vars, cloud creds, SSH keys).
2. Enumerate which packages the compromised identity or team can publish to.
3. Republish malicious versions across each writable package so downstream `npm install` executions create more credential-generation nodes.

This becomes more dangerous when the release workflow uses **trusted publishing**: if the attacker steals the GitHub Actions OIDC material from a job with `id-token: write`, the poisoned release can still receive **valid provenance** because the legitimate workflow really built it. Provenance answers _which workflow built this artifact_, not _whether the workflow/source tree was clean_.

Useful checks:

- Look for workflows that combine `id-token: write` with `npm publish`, `changesets`, or release bots and **do not require a human approval step**.
- Check whether the compromised identity can enumerate org/team package access (for example with `npm access ls-packages`) and whether package publishing bypasses 2FA.
- Add friction to the propagation loop with **staged publishing** / human 2FA approval and `minimumReleaseAge` quarantine before consuming newly published versions.

#### Repository-local AI assistant persistence

A compromised publisher or repo writer does not need to stop at install-time execution. Another persistence layer is to commit **assistant instruction/config files** into the repository so the next developer who opens the project feeds attacker-controlled instructions into local tooling. High-signal paths include:

- `.claude/settings.json`
- `.cursor/rules`
- `.gemini/`
- editor/IDE task or settings files that steer AI helpers

This is useful after CI compromise because the attacker can push those files with a stolen maintainer token, and the trigger later becomes **repository open / assistant load** instead of `npm install`. During reviews, diff for new assistant-policy files with the same suspicion level as new workflow files or build scripts.

#### Alternate exfil when outbound traffic is filtered

If direct exfiltration is blocked but the workflow still has a write-capable `GITHUB_TOKEN`, the runner can abuse GitHub itself as the transport:
Expand Down Expand Up @@ -958,8 +995,12 @@ 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/)
- [Weaponizing the Protectors: TeamPCP’s Multi-Stage Supply Chain Attack on Security Infrastructure](https://unit42.paloaltonetworks.com/teampcp-supply-chain-attacks/)
- [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)
- [What the Miasma campaign reveals about the new supply chain threat model and the underground market for developer credentials](https://www.tenable.com/blog/what-the-miasma-campaign-reveals-about-the-new-supply-chain-threat-model-and-the-underground)
- [Events that trigger workflows - GitHub Docs](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows)
- [Trusted publishing for npm packages | npm Docs](https://docs.npmjs.com/trusted-publishers/)
- [Staged publishing for npm packages | npm Docs](https://docs.npmjs.com/staged-publishing/)
- [Generating provenance statements | npm Docs](https://docs.npmjs.com/generating-provenance-statements/)
- [npm orgs | npm Docs](https://docs.npmjs.com/using-npm/orgs.html)
- [node-gyp README](https://github.com/nodejs/node-gyp)

{{#include ../../../banners/hacktricks-training.md}}