Marshall is what happens when a security researcher gets frustrated with every browser leaking data. It's a privacy-focused web browser built from scratch with Rust and GTK3.
Why Rust?
Every major browser vulnerability report includes memory safety bugs — use-after-free, buffer overflows, type confusion. Rust eliminates entire classes of these bugs at compile time. For a security tool, that's not optional — it's essential.
The performance is a bonus. Marshall's content blocker processes 70,000+ filter rules at startup in under 200ms.
The Ad Blocker
Marshall's built-in content blocker is one of its defining features. It works differently from extension-based blockers:
// Simplified content blocker pipeline
fn process_request(url: &Url, context: &RequestContext) -> Decision {
// 1. Check compiled rule set (O(1) lookup)
if self.compiled_rules.matches(url, context.resource_type) {
return Decision::Block;
}
// 2. Check exception rules
if self.exceptions.matches(url, context.source_page) {
return Decision::Allow;
}
// 3. Apply cosmetic filters
if let Some(css) = self.cosmetic_rules.get(context.domain) {
context.inject_css(css);
}
Decision::Allow
}
By compiling filter lists into an optimized data structure at startup, we achieve O(1) lookups per request. No regex matching in the hot path.
Anti-Fingerprinting
Browser fingerprinting is the tracking technique that cookie blockers can't stop. Marshall fights back on multiple fronts:
| Vector | Marshall's Defense |
|---|---|
| Canvas | Returns randomized pixel data per session |
| WebGL | Spoofs renderer and vendor strings |
| Audio | Adds imperceptible noise to AudioContext output |
| Fonts | Reports only a standard font set |
| Screen | Rounds dimensions to common breakpoints |
| User-Agent | Rotates among popular browser signatures |
The key insight is that you don't need to block fingerprinting entirely — you just need to make your fingerprint indistinguishable from millions of other users.
Tor Integration
Marshall can route traffic through Tor with a single click. It connects to a local Tor SOCKS5 proxy and supports per-tab circuit selection. Each tab can have its own Tor identity, or you can share circuits across tabs for performance.
What I'd Do Differently
If I were starting over, I'd use GTK4 instead of GTK3. The WebKitGTK bindings for GTK4 are now mature enough, and GTK4's rendering pipeline is significantly better. The PineFlip project already uses GTK4 + Libadwaita and the experience is much smoother.
Check out Marshall on GitHub.