WebSocket servers power everything from live dashboards to trading platforms and multiplayer games — but their long-lived, stateful nature makes them a notoriously tricky target for traditional security testing. HTTP fuzzers stop at the handshake, and protocol-level bugs in frame parsers, length fields, or UTF-8 validators rarely show up in functional tests.
That’s where wsfuzz comes in.
Developed in-house at softScheck, wsfuzz is a mutation-based WebSocket fuzzer that combines Radamsa for input generation, async I/O for high concurrency, and raw TCP access for true protocol-level testing. It handles both stateless fuzzing and stateful, scenario-driven workflows. And the best part? We’re releasing it as open-source so the entire security community can benefit.
Why Use wsfuzz?
- Protocol-level testing — reserved opcodes, unmasked frames, RSV bit manipulation, payload length mismatches, invalid UTF-8, malformed close codes, and handshake header fuzzing.
- Application-level testing — Radamsa-powered mutation fuzzing with automatic crash detection via close codes, resets, and exceptions.
- Stateful scenarios — multi-step JSON workflows with setup, capture, expectations, optional HTTP pre-auth, and teardown.
- CSWSH validation — built-in checks for Cross-Site WebSocket Hijacking.
- Harness mode — bridge HTTP-based security tools to WebSocket endpoints via templated injection.
- Smart deduplication — behavior-based fingerprinting keeps the crash list actionable.
- Deterministic replay — reproduce and compare every crash from its artifact.
How It Works
Point wsfuzz at a WebSocket endpoint and it does the rest. A few quick examples:
Basic fuzzing against a local server:
wsfuzz -t ws://localhost:64999
High-concurrency text-mode fuzzing:
wsfuzz -t ws://localhost:64999 -m text -c 10 -n 1000
Raw protocol fuzzing including the handshake:
wsfuzz -t ws://localhost:64999 --raw --fuzz-handshake
Authenticated sessions with custom headers:
wsfuzz -t ws://localhost:64999 -H "Cookie: session=abc" -H "Authorization: Bearer tok"
Stateful scenario testing with connection reuse:
wsfuzz -t ws://localhost:64999 --scenario ./scenarios/orders.json --scenario-reuse-connection
Bridge an HTTP-based security tool to a WebSocket endpoint:
wsfuzz -t ws://localhost:64999/api --harness --harness-template '{"user":"[FUZZ]"}'
Replay previously captured crashes deterministically:
wsfuzz -t ws://localhost:64999 --replay ./crashes
Every crash is saved alongside its raw payload, metadata, seed, and — for scenario runs — a full session transcript. A crash_index.json keeps fingerprints and deduplication counts, so you can triage hundreds of findings without drowning in duplicates.
Get Started
🚀 Ready to start hunting bugs in your WebSocket servers? Give wsfuzz a try!
🔗 Check out the GitHub repo for installation instructions and documentation.
💡 Have feedback or ideas? Open an issue or join the discussion — we’d love to hear from you!
📚 Read about other interesting topics on our blog.