Skip to content

APS creatives requiring nested same-origin semantics render blank #999

Description

@ChristianPavilonis

Description

Some APS creatives do not render even though the APS renderer and Amazon runner initialize. The failure occurs when a creative library expects a nested HTTPS iframe to retain its real origin.

A confirmed example is a Flashtalking Richload creative: its nested Richload iframe remains visibility: hidden with an empty document, so the placement appears blank.

This is separate from the PUC transport, GAM 1x1 shell resizing, and clipping fixes in #998.

Root cause

The APS renderer is served from the publisher origin at:

/integrations/aps/renderer

To keep third-party code isolated from the publisher, the outer renderer iframe and its response CSP deliberately omit allow-same-origin from their sandboxes.

That gives the renderer an opaque origin, but it also activates the sandboxed-origin restriction for the renderer's entire descendant browsing-context tree. A nested iframe cannot loosen an ancestor's sandbox restrictions. Consequently, adding allow-same-origin to the creative iframe created by Amazon's runner is ineffective: the inherited outer restriction still forces it to origin null.

The affected Flashtalking creative then reports errors such as:

SecurityError: Blocked a frame with origin "null" from accessing a cross-origin frame.
Both frames are sandboxed and lack the "allow-same-origin" flag.

TypeError: Cannot read properties of null (reading 'open') at #setupRichload

When the effective sandbox permits same-origin semantics, the Richload iframe receives its expected HTTPS origin, populates its document, and becomes visible.

Security constraint

We should not simply add allow-same-origin to the current publisher-origin renderer.

Combining allow-scripts and allow-same-origin on a publisher-origin document would allow code in that document to access publisher DOM and origin state and potentially remove its iframe sandbox. Any solution must preserve the boundary between APS/creative code and the publisher.

Existing protections should also remain intact:

  • Bounded and canonical descriptor validation
  • Nonce-bound, one-shot message transport
  • Exact source-frame and MessagePort ownership
  • Publisher-origin creative URL rejection
  • Direct-parent compatibility
  • GAM/PUC slot ownership and guarded shell resizing

Potential solutions and trade-offs

1. Naturally opaque data: renderer

Instead of navigating the renderer iframe to a publisher-origin endpoint, embed the static renderer document in a data: URL and apply a sandbox containing allow-scripts allow-same-origin.

A data: document has a naturally unique opaque origin. allow-same-origin therefore does not make it publisher-origin, but it avoids imposing the sandboxed-origin restriction on its HTTPS descendants.

A controlled Chromium proof with the affected Flashtalking creative produced:

  • Renderer origin: null
  • Publisher DOM readable from renderer: no
  • Renderer frameElement readable/removable: no
  • Flashtalking frame origin: https://cdn.flashtalking.com
  • Richload used/loaded: yes
  • Richload visibility: visible
  • Richload document populated: yes

Advantages:

  • No new renderer hostname or service
  • Preserves browser-enforced separation from the publisher
  • Allows nested creative frames to keep their real origins
  • Does not require rewriting vendor creative markup into the publisher document
  • Existing nonce and MessageChannel protocols can remain

Trade-offs and open questions:

  • A data: document cannot receive HTTP response headers. Resource restrictions can use a meta CSP, but CSP directives such as sandbox cannot be equivalently delivered through a meta policy. The iframe sandbox attribute becomes the primary boundary.
  • Publisher and GAM/PUC frame policies must permit data: in frame-src/child-src.
  • location.origin is null, so defense-in-depth validation that currently rejects creative URLs matching the publisher must receive or embed the trusted publisher origin explicitly.
  • The static renderer source moves into the client/PUC program and makes the iframe URL larger and less convenient to inspect.
  • Self-navigation, popup, top-navigation, and sandbox-removal attempts need explicit adversarial tests.
  • Chromium, Firefox, WebKit, direct rendering, and real PUC topology all need validation.

2. Dedicated cross-origin renderer endpoint

Serve the renderer from a distinct browser origin and permit allow-same-origin there.

Advantages:

  • Conventional HTTP response headers and CSP
  • Straightforward origin-targeted messaging
  • Clear isolation boundary when the origin has no other authority

Trade-offs:

  • Requires DNS, TLS, routing, deployment, and publisher CSP changes
  • The origin must be exclusively renderer-only; exposing normal Trusted Server routes under it would weaken the boundary
  • Additional operational ownership for a single integration surface

This may not be operationally acceptable for deployments that do not want a dedicated renderer domain.

3. Render remote iframe creatives directly as siblings

Keep the opaque APS controller but ask trusted publisher-side code to create a direct cross-origin creative iframe outside the opaque controller's descendant tree.

Advantages:

  • Retains a normal HTTPS origin for iframe-tag creatives
  • No additional renderer hostname

Trade-offs:

  • Does not generically support script-tag creatives, where Amazon's runner fetches creative HTML and renders it through srcdoc
  • Requires reimplementing part of Amazon's rendering behavior
  • Risks fragile format- or vendor-specific handling
  • Increases the amount of creative orchestration performed by first-party code

4. Vendor-specific fallback

Detect affected creative formats/vendors and render them through a special path.

Advantages:

  • Potentially narrow implementation

Trade-offs:

  • Brittle and difficult to generalize
  • Requires reliable vendor/format identification before execution
  • Likely to regress as vendor markup changes
  • Creates inconsistent security and rendering behavior

5. Preserve the current opaque renderer

Continue rejecting incompatible same-origin-dependent creatives.

Advantages:

  • No change to the existing security model

Trade-offs:

  • Affected paid placements remain blank
  • Renderer success signals may not reflect whether deeply nested creative content actually painted

Suggested investigation

The naturally opaque data: renderer appears to be the most promising no-domain direction, but it should not be selected without completing the security and compatibility work.

  1. Build a test-only data-URL renderer using the existing static renderer program.
  2. Keep descriptors out of the URL and transfer them only after nonce/source authentication.
  3. Reproduce the current resource CSP with a meta policy and document the directives that cannot be preserved.
  4. Add explicit publisher-origin validation rather than relying on the data document's location.origin.
  5. Run adversarial navigation, popup, storage, DOM-access, sandbox-removal, replay, and wrong-source tests.
  6. Exercise direct APS and real Prebid Universal Creative topologies in Chromium, Firefox, and WebKit.
  7. Add the confirmed Flashtalking Richload creative as a controlled browser regression.
  8. Preserve the current HTTPS renderer as a compatibility fallback until mixed deployments and rollback behavior are defined.

Acceptance criteria

  • Affected nested creatives render and paint at their expected size.
  • Renderer and creative code cannot read or mutate publisher DOM, cookies, storage, or globals.
  • Descendant creative frames retain their intended remote origins.
  • Descriptor, nonce, source, port, timeout, and ownership checks remain enforced.
  • Wrong-origin and publisher-origin creative URLs fail closed.
  • Direct and real PUC paths behave consistently.
  • The solution has cross-browser regression coverage and a documented rollback path.

Metadata

Metadata

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions