Fork Commit Detector

Detect potential imposter commits in GitHub repositories

Paste a GitHub commit URL or enter owner/repo @ sha

Try it with example commits

nodejs/node @ 53bcd114... Signed by Matteo Collina Safe
ramimac/aws-...incidents @ 7e4831c0... Signed Fork (Signed)
No demo yet — unsigned commit with signed tag Fork (Verified Tag)
actions/checkout @ 70379aad... Potential Imposter
aquasecurity/trivy @ 1885610c... Potential Imposter
aquasecurity/setup-trivy @ 8afa9b9f... Potential Imposter
ramimac/aws-...incidents @ 7f153f82... Imposter Tag

Fork commits vs. imposter commits

A fork commit is a technical state: a commit that exists in GitHub's object store but is not in any branch of the repository you're referencing. Due to Git's cross-fork object sharing, commits pushed to any fork become accessible via the parent repository's namespace.

An imposter commit describes intent: using a fork commit to masquerade as part of a trusted repository. Reference one in a CI/CD pipeline (uses: owner/repo@sha) and GitHub fetches it—no merge or review required.

Not all fork commits are malicious. Legitimate scenarios include unmerged PR commits, abandoned branches, or force-pushed history. But the potential for abuse makes them worth investigating.

Risk factors: Unsigned fork commits are higher risk, anyone can claim any author identity. The most dangerous scenario is an imposter tag: when an upstream tag points to a fork commit users referencing that tag execute attacker-controlled code while GitHub displays it as a legitimate release.

SITF: Imposter Commits (T-V002)
Chainguard: What the fork?
Aikido: The Fork Awakens
kernel.org: Cross-fork object sharing is not a bug
StepSecurity: The warning everyone ignores
Truffle Security: Deleted repo data

Real-world incidents & research

API-based detection

This tool runs entirely client-side and makes unauthenticated calls to GitHub's public API. No data is sent to any server besides GitHub.

Detection logic:

GET /repos/{owner}/{repo}/commits/{sha}
Verify the commit exists and retrieve metadata (author, signature status, message).

GET /repos/{owner}/{repo}/commits/{sha}/branches-where-head
Check if this commit is currently HEAD of any branch. If yes → safe.

GET /repos/{owner}/{repo}/commits/{sha}/pulls
Check if this commit was merged via a pull request. If yes → safe.

GET /repos/{owner}/{repo}/tags
If the commit is an unsigned fork commit, check if any upstream tags point to it.

GET /repos/{owner}/{repo}/git/ref/tags/{name} + GET /repos/{owner}/{repo}/git/tags/{sha}
If tags exist, check if they're annotated and cryptographically signed. A signed tag = maintainer vouched for the commit.

If none of the above: the commit exists in GitHub's object store but is not reachable from any branch. This is a fork commit. If unsigned, it's a potential imposter.

Limitations: The branches-where-head endpoint only returns branches where this commit is the current HEAD, not all branches containing the commit. A commit deep in history may show as a fork commit even if it's legitimate. Additionally, pushing a tag without its associated branch will trigger a fork commit warning—the commit exists but isn't branch-reachable yet. Check the commit's signature, tag signature, and author for additional context.