supply-chain-attacks

May 22, 2026 ยท View on GitHub

A catalog of real-world software supply-chain attacks reproduced as safe harnesses, each with cilock detection demonstrated by live CI.

ci docs license cilock

Every entry in this repo is a real attack, a safe synthetic reproduction of it, the cilock policy that catches it, and a CI workflow that proves the policy works on every push. No marketing claims โ€” green badges or red badges, both auditable.

The 7 attacks

DateAttackVectorAffectedDetection layerStatus
2026-05-19Nx Console VS Code extensionIDE extension scope abusenrwl/nx-console, 2.2M+ installsContent (secretscan) + Behavior (trace)๐Ÿ“‹ documented, implementation pending
2026-05-19actions-cool hijackImposter commits via stolen maintainer creds, secrets scraped from /proc/<pid>/memactions-cool/* ActionsPrevention (source policy) + Content (secretscan, 6 findings) + Behavior (/proc/*/mem + /proc/self/environ + /tmp/runner_collected_*)โœ… live detection โ€” all 3 layers green
2026-05-19Shai-Hulud npm wormSelf-replicating malware across published npm packagesdozens of npm packagesContent (secretscan on install scripts) + Behavior (npm install patterns)๐Ÿ“‹ documented, implementation pending
2026-05-18Microsoft durabletask PyPI trojanTrojanized release of a Microsoft-published PyPI packagedurabletask on PyPIPrevention (attestation policy requires upstream attestation) + Content (secretscan on setup.py / .pth)๐Ÿ“‹ documented, implementation pending
2026-05-18GitHub internal source disclosureData exposure / breach, GitHub's own source codeGitHub internal reposN/A at runtime โ€” cilock would have provided forensic attestations from affected build pipelines๐Ÿ“‹ documentation-only
2026-03-24LiteLLM .pth credential stealerPython .pth file executed on every interpreter startup, sweeping credslitellm==1.82.7 and 1.82.8 on PyPIContent (secretscan with recursive base64 decode) + Behavior (/proc/self/environ read)๐Ÿ“– see deep-dive walkthrough
2026-03-19Trivy tag rewrite75/76 version tags force-pushed in aquasecurity/trivy-action, creds stolen from /proc/<pid>/memevery pipeline pinning the action by tagPrevention (SHA pinning enforced by policy) + Content + Behavior๐Ÿ“– full deep-dive in aflock-ai/attestor-compliance-examples/43-trivy-attack-detection

What this repo is

A working answer to the question every dev asks after a supply-chain incident: "would my tooling have caught this?"

For each catalogued attack, this repo ships:

  1. A README with the timeline, IOCs, attribution, and the cilock detection mechanism that catches it.
  2. A safe synthetic payload that reproduces the attack's syscalls / output patterns without any real exfiltration. No live secrets. No network beacons. No live malware.
  3. A signed cilock policy (OPA Rego) that detects the attack at one or more of cilock's three defense layers.
  4. A live CI workflow (.github/workflows/detect-<attack>.yml) that runs the payload through cilock with the policy on every push and turns the badge green or red. If it goes red, the detection broke and the README is now lying.

The harness shape is identical across attacks โ€” the same cilock run + cilock verify pair, the same policy module structure, the same job matrix. Only the payload and the policy details change. That makes it cheap to add a new attack and trivial for a reader to compare detections across attacks.

How detection works

Cilock catches supply-chain attacks at three independent layers, so an attacker has to bypass all three to succeed:

LayerWhat it doesExample detection in this repo
1. PreventionSigned Rego policy restricts which actions, packages, and refs are allowed to run. Enforces SHA pinning. Untrusted refs never execute.actions-cool-hijack/policy-source-restrict.rego denies actions-cool/* refs that aren't SHA-pinned
2. Content detectionThe secretscan attestor runs Gitleaks on stdout and recursively decodes base64, hex, and URL-encoded payloads through three layers. Credential patterns trigger a build fail.LiteLLM .pth stealer caught: the __pycache__-embedded payload is base64-encoded inside the bytecode; secretscan's recursive decoder unwraps it
3. Behavioral detectionThe --trace flag (Linux only) ptraces the wrapped process and records every file each process opens. OPA Rego policies match credential-harvesting filesystem patterns.actions-cool-hijack/policy-trace-behavioral.rego denies any process that reads /proc/<pid>/mem or /proc/self/environ โ€” both are credential-harvesting fingerprints

Defense in depth is the point. A single layer can be bypassed; three independent layers raise the cost to the attacker materially. Each attack catalogued here is annotated with which layers fire, so you can see what bypasses what.

Reproduce any detection locally

The CI workflows run as-is on GitHub-hosted runners. To run any detection locally on Linux:

# Install cilock (one of):
curl -fsSL https://cilock.aflock.ai/install.sh | bash
# or
docker pull ghcr.io/aflock-ai/cilock:latest

# Pick an attack, run its payload through cilock with the policy:
cd 2026-05-actions-cool-hijack
cilock run \
  --step detect-actions-cool \
  --attestations secretscan git environment commandrun \
  --trace \
  --attestor-secretscan-fail-on-detection \
  --signer-fulcio-url https://fulcio.sigstore.dev \
  --signer-fulcio-oidc-issuer https://token.actions.githubusercontent.com \
  --signer-fulcio-oidc-client-id sigstore \
  --timestamp-servers https://timestamp.sigstore.dev/api/v1/timestamp \
  --enable-archivista=false \
  --outfile attestation.json \
  -- bash payload.sh

# Verify against the policies (the detection layer that catches it):
cilock verify --policy policy-source-restrict.rego attestation.json
cilock verify --policy policy-trace-behavioral.rego attestation.json

If the policies detect the attack (and they should), cilock run exits non-zero and cilock verify reports the matching deny rules. That is the detection.

How to add an attack to this catalog

Each subdirectory is independent. To add a new attack:

<date>-<slug>/
โ”œโ”€โ”€ README.md                          # Timeline, IOCs, attribution, detection layer
โ”œโ”€โ”€ payload.sh                          # Safe synthetic reproduction. NEVER include
โ”‚                                       # real secrets or live exfil URLs. Echo synthetic
โ”‚                                       # credential patterns + touch the same syscalls
โ”‚                                       # the real attack hits.
โ””โ”€โ”€ policy-<layer>.rego                 # One or more Rego policies that fire on the attack

.github/workflows/detect-<attack-name>.yml     # CI for this attack. Mirror the shape
                                                # of detect-2026-05-actions-cool-hijack.yml.
                                                # Lives at the repo root because GitHub
                                                # only discovers workflows there.

Open a PR; the top-level CI matrix automatically picks up the new directory. README's table needs a new row.

Ethics + safety

Every payload in this repo is a synthetic reproduction. We exercise the same syscalls and content patterns the real attack used, but:

  • No real credentials. Payloads echo strings shaped like AWS keys, GitHub PATs, RSA private keys โ€” but the values are not real secrets and have never been valid.
  • No live exfiltration. Payloads do not perform any network egress. No DNS queries. No HTTP. The behavior layer fires on filesystem access patterns, not on outbound traffic.
  • No malware redistribution. We do not host copies of the real malware. The IOCs (file paths, package names, version numbers, hashes) are documented for forensic reference; the original sources cited in each attack's README are the place to obtain real samples if you have a legitimate research reason.

This repo is a defensive demonstration, not an offensive toolkit.

License

Apache 2.0 โ€” see LICENSE. Built and sponsored by TestifySec.