Uh oh!
There was an error while loading. Please reload this page.
Use configured publisher domain for navigation-path auction requests - #937
Conversation
build_auction_request derived publisher.domain, site.domain, and the page URL host from the incoming request Host header. On the SSAT proxy path that header is the trusted-server edge host (e.g. the staging domain), which then leaked into the outbound OpenRTB bid request and, through it, into injected creatives and the IAS brand-safety pixel. Source these fields from settings.publisher.domain instead, matching what convert_tsjs_to_auction_request already does on the /auction endpoint path. Closes#936
…n requests) into rc/july # Conflicts: # crates/trusted-server-core/src/publisher.rs
prk-Jr
left a comment
There was a problem hiding this comment.
Summary
Fixes the navigation-path (SSAT/SPA) AuctionRequest builder so publisher.domain, site.domain, and the page URL host come from the configured settings.publisher.domain instead of the incoming edge Host header, matching the pattern already used by convert_tsjs_to_auction_request on the /auction path. Minimal, well-targeted diff (publisher.rs only) with a solid test-first regression test.
Non-blocking
🌱 seedling
- Scheme source differs between the two
AuctionRequestbuilders:build_auction_request(publisher.rs:2021) still derivespage_url's scheme fromrequest_info.scheme(edge-detected), whileconvert_tsjs_to_auction_request(auction/formats.rs:202) hardcodes"https"for the same field. Not a bug today (the edge always terminates TLS ashttpsin production), but worth aligning in a follow-up so both builders source scheme the same way.
👍 praise
- Test-first regression coverage:
auction_request_uses_configured_publisher_domain_not_edge_hostuses a deliberately divergent edge host (ts.example.com) vs. configured domain (www.example.com) and asserts all four leak points (publisher.domain,site.domain,page_url,site.page). Confirmed to fail on the pre-fix code per the PR description.
CI Status
- fmt: PASS
- clippy: not reported as a distinct check (cargo check jobs pass)
- rust tests: PASS (fastly/axum/cloudflare/spin, cross-adapter parity)
- js tests (vitest): PASS
- integration tests: PASS
ChristianPavilonis
left a comment
There was a problem hiding this comment.
Summary
The core OpenRTB/APS domain correction is narrow and correct. Approving with two follow-up findings noted inline: navigation telemetry still uses the edge host as publisher_domain, and the new regression test covers the helper rather than the production handlers.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…main The navigation-path AuctionObservationContext still took its publisher_domain from the incoming edge Host header, so telemetry rows for initial and SPA navigations were attributed to the edge/staging host while /auction rows and outbound bid requests used the configured publisher domain. Both observation constructors now use settings.publisher.domain. Add handler-level coverage for both navigation paths: the previous regression test called build_auction_request directly and would keep passing if a call site reverted to request_info.host, since both sources are &str. The new tests drive handle_publisher_request and handle_page_bids with a divergent edge host, capture the dispatched AuctionRequest through a recording provider, and assert both the bid request fields and the emitted telemetry rows carry the configured domain. Verified they fail when either the builder argument or the observation argument is reverted.
Uh oh!
There was an error while loading. Please reload this page.
The #937 squash on main and rc/july's copy of the same change diverged on one line: rc/july renamed MatchedSlotsContext::request_path to request_path_and_query. Keep rc/july's field name — request_path no longer exists on this branch. # Conflicts: # crates/trusted-server-core/src/publisher.rs
Summary
On the navigation / SSAT proxy path, the server-side auction advertised the incoming request
Hostheader — which on that path is the trusted-server edge host (e.g. the staging domain) — as the publisher domain. That value flowed into the outbound OpenRTB bid request and, through it, into injected creatives and the IAS brand-safety pixel, so both carried the edge/staging host instead of the real publisher domain.build_auction_requestsetpublisher.domain,site.domain, and thepage_urlhost fromrequest_info.host. This change sources those fields fromsettings.publisher.domaininstead — matching whatconvert_tsjs_to_auction_requestalready does on the/auctionendpoint path.Closes#936.
Root cause
Two
AuctionRequestbuilders derived the publisher host from opposite sources:convert_tsjs_to_auction_request(auction/formats.rs) — used config (settings.publisher.domain). ✅build_auction_request(publisher.rs) — used the raw incomingHostheader. ❌ (navigation path:AuctionSource::InitialNavigationandSpaNavigation)PR #934 only corrected
ext.trusted_server.request_hostinside the Prebid provider; it did not touchsite.domain/site.publisher.domain/site.page, and on the navigation pathrequest.publisher.domainwas itself the poisoned edge host. This fixes the builder at the source.Changes
publisher_domain: &strparameter tobuild_auction_requestand use it forpublisher.domain,site.domain, and thepage_urlhost (scheme and path are unchanged).&settings.publisher.domain.auction_request_uses_configured_publisher_domain_not_edge_host: with a divergent edge host (ts.example.com) and configured domain (www.example.com), the bid request advertises the configured domain forpublisher.domain,site.domain,page_url, andsite.page. Written test-first (verified it fails on the old behavior before the fix).Test plan
cargo fmt --all -- --checkcargo test-fastly(wasm — core + fastly, incl. new regression test)cargo test-axum(native — shared core)cargo clippy-*— could not run locally:clippy-fastlyfails in thetrusted-server-jsbuild script (Unrecognized option: 'p'), which reproduces on unmodifiedmain, so it is a pre-existing local-environment issue unrelated to this change. Deferred to CI.Notes
Targets
main(the buggy code exists onmain, not just the release branch). Can be cherry-picked / merged intorc/julyas needed.