Distribution bundle drift

ID

dist_bundle_drift

Severity

high

Resource

System

Tags

attack-T1195.001, cwe-506, dropper, supply-chain

Description

This detector flags a JavaScript GitHub Custom Action whose committed dist/ bundle references a high-signal capability — a CI secret, runner-memory access, a known exfiltration endpoint, or decode-and-eval — that does not appear anywhere in the action’s first-party source. In other words, the published artifact does something the source never does.

It is fully static: it only reads files and matches regexes. It deliberately does not install dependencies, build, or execute anything, because the input is potential malware and running its build tooling would execute attacker-controlled code on the scanner.

Rationale

JavaScript actions ship a pre-built, committed dist/ bundle that is what actually runs in CI — reviewers read the source, but the runner executes the bundle. An attacker who can push a bundle that diverges from the source can run code no one reviewed: read secrets/GITHUB_TOKEN, scrape the runner’s process memory, or POST credentials to an exfil endpoint, all while the human-readable source stays clean. A source-vs-bundle capability delta is the tampered-bundle signature.

  • tj-actions/changed-files (March 2025, CVE-2025-30066) — the compromised action’s committed bundle dumped runner memory and CI secrets into build logs, while the repository source did not obviously reveal it.

  • reviewdog actions (March 2025, CVE-2025-30154) — part of the same supply-chain wave, with a tampered published artifact used to steal credentials from CI.

  • The pattern generalizes to any "source looks clean, shipped bundle is malicious" attack on pre-built JS action artifacts and npm postinstall-style droppers.