Uh oh!
There was an error while loading. Please reload this page.
Fix ext.trusted_server.request_host to use the publisher domain - #934
Conversation
On the SSAT proxy path the browser calls /auction against the trusted-server edge domain (e.g. ts.example.com), which was leaking into ext.trusted_server.request_host on the outbound Prebid Server request. That field must track the publisher's own domain instead, matching site.domain/publisher.domain and what PBS's trusted_server verification module expects.
aram356
left a comment
There was a problem hiding this comment.
Summary
Correct, well-scoped change. ext.trusted_server.request_host (and the signed host in SigningParams) now comes from the validated publisher.domain instead of the raw incoming Host header, which on the SSAT proxy path is the trusted-server edge host — not what PBS's trusted_server verification module expects. CI is fully green and the regression test is meaningful. Approving.
Notes
📝 Scope: correct on the /auction path; navigation path is covered by #937
The fix is correct wherever request.publisher.domain is the publisher's own domain — which holds on the /auction endpoint path, where convert_tsjs_to_auction_request sources it from the validated settings.publisher.domain.
On the SSAT navigation path, build_auction_request (crates/trusted-server-core/src/publisher.rs) still populates publisher.domain/site.domain from request_info.host (the edge host), so on that path request_host would remain the edge host. That builder is fixed at the source by #937, which also corrects site.domain/site.page/page_url (untouched here). The two compose cleanly: because this PR reads publisher.domain at runtime, #937 making that field correct on the navigation path makes this PR's request_host correct there too. No ordering dependency, no conflict.
📝 Scheme is now canonical https, not request-derived
request_scheme (and the signed scheme) is now hardcoded to "https" rather than detected via TLS. Defensible — the publisher origin is https in production — but it's a behavior change the code comment doesn't call out (the comment justifies only the host). Worth a one-line note that the scheme is intentionally canonical, and confirming PBS verifies https unconditionally (relevant for local fastly compute serve over http). Non-blocking.
👍 Praise
StubHttpClient::send_asyncbody capture mirrorssend()and propagates capture failures via?instead of silently recording an empty body — a capture failure can't masquerade as an intentionally empty body.- The regression test uses a distinct edge host (
ts.pub.example) vs publisher domain (pub.example), so the assertion actually catches the leak rather than passing vacuously;.exampledomains throughout, per project guidelines.
CI Status
- fmt: PASS
- clippy: PASS
- rust tests (fastly / axum / cloudflare / spin): PASS
- cross-adapter parity: PASS
- js (vitest) + format: PASS
- integration / browser: PASS
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Addresses review note on the ext.trusted_server.request_host fix: the comment justified only the host, not why scheme is hardcoded.
Uh oh!
There was an error while loading. Please reload this page.
Resolve prebid.rs conflict from #934: rc/july already uses the publisher domain for ext.trusted_server.request_host; keep main's explanatory comment on the canonical https scheme.
Summary
ext.trusted_server.request_hoston outbound Prebid Server auction requests was set from the raw incomingHostheader, which on the SSAT proxy path is the trusted-server edge domain (e.g.ts.example.com), not the publisher's own domain.AuctionRequest.publisher.domain(scheme fixed tohttps), matching howsite.domain/publisher.domainare already built, and matching what PBS'strusted_serververification module expects ("Host header value expected by the receiving service").Changes
crates/trusted-server-core/src/integrations/prebid.rsPrebidAuctionProvider::request_bidsnow buildsrequest_infofromrequest.publisher.domaininstead ofRequestInfo::from_request(raw edgeHostheader). Added a regression test assertingext.trusted_server.request_hostmatches the publisher domain, not the edge host.crates/trusted-server-core/src/platform/test_support.rsStubHttpClient::send_asyncnow captures the outgoing request body (mirroringsend()), so tests exercising the async fan-out path can assert on outbound bodies viarecorded_request_bodies().Closes
Closes#888
Test plan
cargo test-fastly && cargo test-axum && cargo test-cloudflarecargo clippy-fastly && cargo clippy-axum && cargo clippy-cloudflarecargo fmt --all -- --checkcd crates/trusted-server-js/lib && npx vitest runcd crates/trusted-server-js/lib && npm run formatcd docs && npm run formatcargo check-fastly(wasm32-wasip1)fastly compute serveChecklist
unwrap()in production code — useexpect("should ...")tracing/logmacros (notprintln!)