Security
Hardening pass 1 — fuzzing and wire-level attacks (2026-10-09)
Development VM (Ubuntu 24.04, Linux 6.8), commit 4f5c52f.
Fuzzing (fuzz/, cargo +nightly fuzz run <target> -O)
Ten minutes per target, libFuzzer with AddressSanitizer, -max_len=8192, seeded with
real inputs (WordPress .htaccess, benchmark configurations, PROXY v1/v2 lines, …).
| Target | Input | Executions | Coverage | Crashes |
|---|---|---|---|---|
range | Range header + file length | 260.9 M | 183 | 0 |
request_host | Host / :authority | 270.8 M | 130 | 0 |
proxy_protocol | PROXY v1 / v2 | 120.6 M | 188 | 0 |
request_path | request path (+ invariants: no dot or empty segments) | 71.5 M | 323 | 0 |
cgi_head | CGI head from PHP | 15.8 M | 1 441 | 0 |
forwarded_for | X-Forwarded-For via trusted proxy | 12.5 M | 262 | 0 |
cache_control | Cache-Control | 4.8 M | 341 | 0 |
config | YAML configuration | 2.0 M | 14 516 | 0 |
htaccess | .htaccess | 0.6 M | 10 081 | 0 |
HTTP/1 and HTTP/2 framing is hyper/h2’s (fuzzed upstream); it is covered below at the wire level instead.
Wire-level tests (tests/integration/tests/{smuggling,security}.rs)
- 14 smuggling shapes — TE.CL, duplicate / obfuscated Transfer-Encoding (
xchunked, space before colon, vertical tab, quoted, folded, upper case), TE on HTTP/1.0, Content-Length+5/ list / hex, NUL in a header, chunk-size overflow: at most one response, the connection closes, and the hidden request never reaches the upstream. - Pipelining: three requests in one write are answered in order, each upstream once.
- Slowloris (headers), slow body, idle keep-alive, silent connections, and a client that
stops reading (cut off by
write_timeout). - HTTP/2 rapid reset (CVE-2023-44487): 2 000 open-and-cancel streams get GOAWAY and a close; other clients are still served.
Privilege separation (systemd units)
scalwsd.service had MemoryDenyWriteExecute=true. scalwsd starts Node.js and Python
applications, which inherit it: Node.js aborted at start-up and PHP opcache.jit
could not work. Removed (4f5c52f); every other restriction verified with Node.js.