Detects invisible network exploits in GitHub Actions pins
Project description
WTFork 🤌🤌
Pinning to SHA isn't the silver bullet you think it is.
This tool detects if your GitHub Actions are vulnerable to the Fork Network exploit (a.k.a. "The Invisible Network"), verifying that the commits you pin actually belong to the repositories you trust.
This project is inspired by this Aikido’s write-up on how fork networks work, and how Sai-Hulud was abusing it:
The Fork Awakens: Why GitHub’s invisible networks break package security
🚩 The Problem: "Invisible Networks"
Security best practices tell us to pin GitHub Actions to a full commit SHA (uses: owner/repo@<sha>). The assumption is simple: "If I pin the SHA, I trust code I'm running." Strict immutability usually equals strict trust
That assumption is wrong.
GitHub's architecture creates a loophole. It resolves SHAs across the entire fork network, not just the target repository.
This means uses: owner/repo@<sha> guarantees the code (the SHA), but it does not guarantee the source. A commit might resolve successfully from any fork, even if it never existed in the trusted owner/repo, effectively pulling unreviewed code from an obscure or malicious fork while appearing to come from upstream.
The Worst Case Scenario:
- Your workflow defines:
uses: trusted-owner/action@<sha> - That
<sha>does not exist intrusted-owner/action. - However, GitHub resolves it to a malicious commit in an obscure fork.
- You unknowingly execute
untrusted-owner/action@<sha>from a different owner you never agreed to trust.
🛡️ How WTFork works
wtfork audits your repository’s GitHub Actions workflow files to validate that every referenced SHA is legitimate.
It scans:
.github/workflows/*.yml.github/workflows/*.yaml
For every uses: owner/repo@<sha> found, wtfork performs a sanity check: Does this commit actually live inside owner/repo?
If the SHA is missing from the origin repo (but resolving due to the fork network quirk), wtfork flags it immediately so you can fix the pin before it becomes a supply-chain attack vector.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wtfork-1.0.0.tar.gz.
File metadata
- Download URL: wtfork-1.0.0.tar.gz
- Upload date:
- Size: 3.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecfa5b67c7ad23c50be11a243eaa3e323ca0b2019e9b30d9ec35edaf4d15c1c9
|
|
| MD5 |
7232ebb8627a27fc7928b1c7329566c0
|
|
| BLAKE2b-256 |
73dbb1e70bdc872320c848ddfc81c50686450a01f6a7eb9f54a896f7387384aa
|
File details
Details for the file wtfork-1.0.0-py3-none-any.whl.
File metadata
- Download URL: wtfork-1.0.0-py3-none-any.whl
- Upload date:
- Size: 5.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d42435370b6ff5b7cdcac0f6988d151f97807d1f89848dc19a1a12e3da9123d5
|
|
| MD5 |
958f077e3cdd9a51ff9e695e866c35ee
|
|
| BLAKE2b-256 |
e7c7f6aa855a8d2251e15ea6f1c5c57871097532e52b03b4051423ea6505b67f
|