fix(gateway): enforce bounded HTTP header mediation - #441
seonghobae merged 40 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
seonghobae
left a comment
There was a problem hiding this comment.
Fresh exact-head review found one additional singleton-response ambiguity in src/gateway_mediation.rs: admit_response_headers() rejects duplicate Content-Type but currently admits multiple Location and Retry-After field lines because both are allowlisted and appended with multiplicity. RFC 9110 §10.2.2 defines Location = URI-reference, explicitly states the field value consists of a single URI-reference, and notes that multiple Location field lines are invalid/interoperability-hostile. §10.2.3 likewise defines Retry-After = HTTP-date / delay-seconds as one value. WWW-Authenticate is intentionally different and may retain list/multiple challenge semantics.
Please extend the #440 hostile contract before wiring this module into the live proxy path: duplicate Location and duplicate Retry-After from a real loopback upstream must fail closed without relaying an ambiguous field/body as a successful buyer response; a single value for each remains preserved. Minimum causal source repair should treat these two as response singletons alongside Content-Type, without collapsing multiplicity for WWW-Authenticate or x-wardnet-app-meta. Keep this in the existing #441 source-writer lane rather than opening a second production writer.
|
Exact hostile RED is now valid for the response-singleton follow-on. Child #446 at Minimum causal repair is now on this sole source-writer lane at exact #446 was non-force restacked by ordinary two-parent merge to exact |
test(gateway): reject ambiguous singleton responses
|
Fresh exact-head documentation review found a code-current drift introduced by the #447 minimum repair. At Do not move #441 solely to repair the prose while test-only child #448 exact This is a deferred same-writer documentation repair, not authorization for a parallel source/docs PR. |
…oding-red test(gateway): preserve coded representation metadata
534a48b
into
codex/coraza-header-enforcement-red-20260917
Refs #440.
Scope / writer authority
This is the serialized Wardnet-owned RED→GREEN lane for generic gateway HTTP mediation. Wardnet owns this gateway/SOC policy boundary. This PR does not copy EgressWeave transport authorization, quarantine-sandbox-runtime isolation, contextual-orchestrator routing, appguardrail logic, or sibling-owner implementation.
Established RED and bounded mediation repair
Hosted predecessor
e32a620fa66232405adbd1603327bb5abcf55b4areached the real loopback buyer fixture after checkout/toolchain/format/unit GREEN and failed five intended cases: admitted requestContent-Typeomitted; duplicateX-Admin-Tokenreached upstream; duplicate requestContent-Typeaccepted; aggregatex-wardnet-app-metabeyond 16,384 bytes accepted; admitted upstreamapplication/jsonreplaced by synthesizedapplication/octet-stream. Exact4b938342ec1bc7f8dd2a1001cfcdf6a0136ccbcaindependently reproduced the same semantic RED in CI35846750623after 146 existing library tests passed; Fuzz35846750936was SUCCESS.The source repair is wired through
src/gateway_mediation.rs. It admits only bounded application metadata, rejects ambiguous request authority/singletons, strips credentials/authority/framing and dynamicConnectionnominations, and reconstructs downstream responses from an explicit allowlist. Coraza parent #435 remains owner of its own authority/evidence seam and is adopted rather than duplicated.The earlier complete candidate
68fc8ed6e6b9644d3406f0bf0c31113e7c1b76e0obtained hosted exact-head CI35864827991SUCCESS and Fuzz35864828031SUCCESS.Response-singleton finding and GREEN
Fresh standards review found that the candidate rejected duplicate response
Content-Typebut admitted repeatedLocationandRetry-After. RFC 9110 §10.2.2 definesLocation = URI-referenceand notes multiple Location field lines are invalid/non-interoperable; §10.2.3 definesRetry-After = HTTP-date / delay-seconds.WWW-Authenticateand boundedx-wardnet-app-metaintentionally retain multiplicity.Test-only child #446 predecessor
a6869e8b2fb1e3c6b9eb6e7d893950693297e864established a real duplicate-Retry-AfterRED. Its initial duplicate-Locationwitness used302 Foundand was confounded because reqwest followed the redirect before Wardnet could inspect the original response envelope. Exact childb8b5804b655a424967252d8ac22172eb4a1338fbisolated the Location case on201 Created; CI35918347719, rust job107375610618, completed format, locked workspace tests and strict Clippy successfully. #446 was then normally merged into this lane as two-parent mergebac6df06d810e977129d601628f14deb1a6381c7.The Wardnet-owned minimum response-singleton repair rejects duplicate
Content-Type,Location, andRetry-Afterwhile retaining legal multiplicity forWWW-Authenticateand boundedx-wardnet-app-meta.The automatic-redirect specimen is a separate outbound-authority integration gap. Exact evidence and acceptance were handed to canonical EgressWeave Rust-consumer issue #237. Wardnet does not implement a second destination/DNS/redirect/proxy/TLS policy; EgressWeave still has no immutable GitHub Release for Wardnet to consume.
Content-Encoding finding and minimum causal repair
Issue #447 / test-only child #448 established the representation-metadata defect. Wardnet's active reqwest feature set does not enable transparent gzip/brotli/deflate decoding, so removing
Content-Encodingwhile relaying coded bytes changes the representation contract. RFC 9110 §§5.2-5.3, 8.1 and 8.4 defineContent-Encodingas representation metadata and allow ordered list-valued coding fields; it is not hop-by-hopTransfer-Encodingand must not be treated as a singleton.Exact hostile child
8a254028faf4db0485ba8710945c2781a876fbedreached the intended tests in CI35917178809, rust job107371632198. Formatting and all 151 library unit tests passed first. Both real loopback buyer-path cases then failed semantically because coded request/response bytes crossed Wardnet whileContent-Encoding: gzipwas absent (left: None,right: Some("gzip")). This is the valid RED authorizing a source repair in this sole writer lane.The minimum causal production repair first reached exact
16a0d0807692203dabc83823793dcefef087c661:content-encodingjoined the bounded request/response mediation allowlists, legal repeated coding values are preserved in order, dynamicConnection: ... content-encodingnominations still strip the field, and no automatic decompression or foreign transport policy is introduced. Owned unit contracts cover orderedgzip,brmultiplicity in both directions and nomination stripping.#448 adopted that parent non-force through ordinary restack PR #449. Exact child
30b52cae32b7022237c552aa6224ebd7d9dfb632retained onlytests/gateway_content_encoding.rsas its effective child delta. Fresh exact-child CI35941616793completed SUCCESS and fresh review/thread inventory was empty. #448 was marked Ready and normally merged into this lane with fixed expected-head protection as two-parent mergecd3c5985fd6317ab80c888fe1e37786f94d780e8.Current #441 is therefore exact
cd3c5985fd6317ab80c888fe1e37786f94d780e8, based exactly on #43511e7fabfca76e0051fa883905228a0dbe472f4df. Fresh exact-head CI35962640235and Fuzz35962640233are queued. Predecessor GREEN does not transfer after child integration.Integration boundary
Before normal integration into #435 and later protected main on an unchanged exact lineage:
cd3c5985fd6317ab80c888fe1e37786f94d780e8must reacquire terminal-valid repository evidence; its queued current-head checks are incomplete evidence and must not be blind-rerun;Release readiness remains separate: version/CHANGELOG/tag/package/immutable release/SBOM/provenance/reproducibility/rollback are required before a release-ready protected head. No force push, destructive rebase, self/model approval, gate weakening, routine administrator bypass, mutable sibling dependency, source copy, cross-service SQL, predecessor-evidence reuse, or blind rerun.