Inspiration

In 2018, the event-stream package was compromised to steal Bitcoin wallets — and it didn't just hit one project, it reached 21+ downstream packages through a single malicious dependency. That's the pattern behind nearly every major supply-chain incident: a dependency tree tells you how code arrived, but it says nothing about how an attacker moves once they're in — through shared maintainer tokens, poisoned CI hooks, or credentials reused across npm and PyPI. Security teams scan one registry at a time and call it coverage, while the actual exposure is transitive, persistent, and cross-ecosystem. We wanted to see the whole blast radius, not just the immediate dependency.

What it does

BlastRadius is a real-time supply-chain threat analyzer. Search any package and get its full transitive blast radius in under a second: how many packages and services are exposed, the exact attack path down to the affected service, a maintainer risk score, and a persistence multiplier estimating how long a compromise survives after the package is pulled. It runs six analyses on one shared graph — blast radius query, typosquat detection, maintainer risk scoring, cross-ecosystem correlation, CI/CD persistence tracking, and compromise simulation — so a finding in one view resolves to the same nodes everywhere else.

How we built it

The core is a graph-native architecture on HydraDB, chosen specifically because dependency exposure isn't a relational problem — it's a traversal problem. We model five distinct edge types (depends_on, installs_persistence, propagates_via, shared-npm-token, shared-github-org) instead of collapsing everything into a single dependency edge, which lets us traverse attacker movement the same way we traverse a manifest. Registry sync continuously pulls package metadata, versions, and maintainer history from npm and PyPI; that data is constructed into the typed graph; queries traverse it for real-time blast radius and shortest-path calculation; and a scoring layer combines CVSS data, maintainer health signals, and transitive depth to prioritize findings. The frontend is React 19 + Vite with a force-directed graph visualization; the backend is Express 5 with a REST API, seeded and deployed serverless-ready on Vercel and Netlify.

Challenges we ran into

Getting sub-second traversal at scale was the hardest part — a naive recursive query over a 10,000-package graph is a 4–5 second wait on a relational database, which is useless for something meant to feel interactive. We had to lean fully into HydraDB's graph-native traversal to get median full-graph queries down to 312ms for 8-hop radius queries. Typosquat detection also took real tuning: edit-distance alone produces too many false positives on legitimate variant packages (like lodash-es), so we added keyboard-adjacency scoring and a whitelist, which brought false positives down to 2.1% while holding recall high.

Accomplishments that we're proud of

We validated the system against incidents that actually happened rather than synthetic data: 91.0% F1 on typosquat detection across 45 known malicious packages and 400 near-miss legitimate names, and 100% recall on documented supply-chain incidents — event-stream, ua-parser-js, coa, and rc — all correctly detected when present in the graph. The full test suite passes at 45/45 (100%), and the whole thing runs cold — clone, install, seed, start — in under 5 minutes, which mattered a lot to us since we wanted judges to actually be able to run it, not just watch a video.

What we learned

The biggest shift was realizing that dependency graphs and attack-movement graphs aren't the same object, even though everyone treats them as if they are. Modeling persistence and credential-sharing as first-class typed edges — instead of bolting them on as metadata — is what actually made cross-ecosystem correlation and CI/CD persistence tracking possible. We also learned a lot about the gap between "graph traversal that works" and "graph traversal that's fast enough to feel real-time" — that 312ms number took real iteration on query depth and result limits to hit.

What's next for BlastRadius

Scaling the index from 10k to the full npm + PyPI registries, adding real-time webhook ingestion so newly disclosed compromises propagate into the graph within minutes instead of at the next sync, and building CI/CD pipeline integrations (GitHub Actions, GitLab CI) so blast radius checks run automatically on every dependency bump rather than requiring a manual search.

Built With

Share this project:

Updates