fix(vm): clamp attacker-controlled HTTP status codes to avoid a gateway crash - #519
Merged
Merged
Conversation
…ay crash net/http's WriteHeader panics for a status code < 100 or > 999. For a gateway-fronted substrate function, that panic runs on the gateway's response-forwarding goroutine (p2p/streams/tunnels/http Frontend), which has no net/http recover — so an out-of-range code crashes the shared gateway process. It is reachable two ways: a tenant's WASM function via the event ABI, and any peer speaking the http-tunnel protocol. - eventHttpRetCode / eventHttpRedirect: reject a code outside 100..999 with errno.ErrorHttpWrite before it reaches WriteHeader / http.Redirect. - tunnel headersOp: clamp an out-of-range wire code to 500 before WriteHeader — the single choke point for any code arriving over the tunnel. - Frontend goroutine: recover a residual panic on that untrusted-frame path into an error instead of taking down the process (defense in depth). Regression tests for each, verified to fail on the pre-fix code with the exact WriteHeader panic. The default no-retcode flow and valid 100..999 codes are unchanged (existing wazy harness still green).
taubyte0
approved these changes
Aug 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
net/http'sWriteHeaderpanics for a status code< 100or> 999. For a gateway-fronted substrate function, that panic runs on the gateway's response-forwarding goroutine (p2p/streams/tunnels/httpFrontend'sgo func()), which has nonet/httpper-request recover — so an out-of-range code crashes the shared gateway process. It's reachable two ways:eventHttpRetCode/eventHttpRedirect), andCodein a headers frame).Fix
eventHttpRetCode/eventHttpRedirect(pkg/vm-low-orbit/event/{code,redirect}.go) — reject a code outside100..999witherrno.ErrorHttpWritebefore it reachesWriteHeader/http.Redirect.headersOp(p2p/streams/tunnels/http/handler.go) — clamp an out-of-range wire code to500beforeWriteHeader. This is the single choke point for any code arriving over the tunnel (a forwarded guest code or a raw peer).Frontendgoroutine —recovera residual panic on that untrusted-frame path into an error instead of crashing the process (defense in depth).The predicate is byte-identical to
net/http's own (code < 100 || code > 999), so100and999pass and nothing legitimate is over-clamped.Tests
Regression tests for each site, each verified to fail on the pre-fix code with the exact
WriteHeaderpanic:pkg/vm-low-orbit/event/status_test.go—eventHttpRetCode/eventHttpRedirectreject0, 99, 1000, …; a valid418passes through.p2p/streams/tunnels/http/status_test.go—headersOpclamps0, 99, 1000, -1, 2000000to500; a valid404passes through.The default no-retcode flow (body-only, implicit
200) and valid100..999codes are unchanged; the existingpkg/vm-low-orbit/testswazy harness (incl.TestRedirect) stays green.