Introducing wsfuzz: A Mutation-Based WebSocket Fuzzer

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.

View on GitHub


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.