Skip to content

CVE coverage ​

What stops a specific, named CVE's request shape in front of zion, verified against a real vulnerable version and a real patched one, not asserted from the advisory alone.

Every row below is produced by tests/lab/ (issue #699): a real container of the vulnerable version, a real container of the patched version, and a real zion in front of the vulnerable one, driven with the exact request shape the advisory describes — never a weaponized payload. covered means the vector works on the vulnerable version, does not work on the patched one (so the oracle is proven to tell them apart), and does not work through zion. Reproduce any row with:

cargo build --release --bin zion
python3 tests/lab/run.py <stack> --zion-bin target/release/zion

A row is added here only after that command prints covered and every [[benign]] step ok — the lab's own rule (tests/lab/README.md), not a separate claim made here.

CVEAdvisoryLab-tested versionsStackWhat stops it
CVE-2025-29927Next.js middleware authorization bypass (the advisory lists further affected ranges across 11.x–15.x; the lab pins one of them)14.2.24 vulnerable → 14.2.25 fixednextjsBuilt-in: zion strips X-Middleware-Subrequest unconditionally (header_policy.rs's BUILT_IN_STRIP) — no configuration needed
CVE-2017-1001000WordPress REST API id param override authorization bypass (advisory also lists 4.7.0 affected; the lab pins 4.7.1)4.7.1 vulnerable → 4.7.2 fixedwordpressVirtual-patch rule wordpress-rest-posts-id-param-override (examples/virtual-patch.toml, #698)

Verified 2026-11-03, zion 0.16.0 (master). Both break-tested: the specific defense disabled, the lab's verdict flips from covered to bypass; restored, covered again.

Not yet covered ​

tests/lab/ has stacks for exactly the two rows above. The issue that opened this page (#699, Real-stack CVE hardening) also named PHP-FPM, Tomcat and Django as candidate stacks; none has a lab result yet, so none gets a row — a row here with no lab behind it would be exactly the unproven claim this page exists to avoid. Building one is tracked in #699, one PR per stack.

Config presets ​

A deployment in front of one of the stacks above can use its own preset:

WordPress ​

toml
[virtual_patch]
rules_file = "/etc/zion/virtual-patch.toml"   # the wordpress-rest-posts-id-param-override
                                               # rule of examples/virtual-patch.toml, or the
                                               # whole starter pack

[server]
h2_control_frames_per_sec = 1000

Next.js ​

No extra configuration: the built-in strip documented under Headers that are not passed on from clients already covers CVE-2025-29927 on every route.

toml
[server]
h2_control_frames_per_sec = 1000

h2_control_frames_per_sec for these presets ​

Decided here (#700): 1000, in both presets above. The hardening guide already measured curl, nghttp and h2load at 2 control frames a second and Chrome at 2 to 3 — 1000 leaves over 300 times that headroom — and its one documented exception is gRPC, which none of WordPress, Next.js, PHP-FPM or Django serve. zion's own global default stays 0 (no limit): a preset is free to assume "no gRPC behind this route", but the schema default has to be safe for every deployment, including ones that do run gRPC and have not measured their own traffic with zion_h2_control_frames_peak yet.

[server] h2_control_frames_per_sec is instance-wide, not per route. It closes the connection, before zion has looked at which route (or upstream) the request is even for — there is no per-route override. 1000 is the right number for a zion instance that serves only one of these presets. If the same instance also fronts a gRPC service — on any route, any port — that service's connections are bound by the same 1000 too, and the hardening guide's own numbers show real gRPC traffic exceeding it even on loopback. A mixed deployment needs to either measure its own gRPC traffic with zion_h2_control_frames_peak first and set the limit above that, or leave h2_control_frames_per_sec at 0 and give up this specific hardening for the whole instance.

See also ​

  • Hardening — the runtime options these shields are built from (#693–#698).
  • HTTP conformance — the request-shape contract this page's probes sit beside, for non-CVE behaviour.
  • tests/lab/README.md — the lab itself: how a probe is judged, what [[benign]] checks for false positives, and why it does not run on pull requests.

Released under the MIT License. · Privacy & legal