prebid / prebid-universal-creative

Apache License 2.0
43 stars 71 forks source link

Expection when iframe with UC is in srcdoc iframe #147

Open Zer0Divis0r opened 2 years ago

Zer0Divis0r commented 2 years ago

Problem On web, when universal creative is loaded in an iframe with srcdoc attribute, or src=about:blank, or blob URL, an exception happens when postMessage is sent. In my case, the specific error message would be:

DOMException: Failed to execute 'postMessage' on 'Window': Invalid target origin 'about://a65bbe00eb976c003b3913c8207a7a4f.safeframe.googlesyndication.com' in a call to 'postMessage'.

To Reproduce The following example would create an iframe and use blob to create it's contents.

let auctionFrameCode = `
<body style="background-color:white;margin:0px;padding:0px;">\x3Cscript src=".....a code that runs auction and eventually loads UC....">\x3C/script></body>`;

let $auctionFrame = jQuery("<iframe srcdoc=''></iframe>");
// OR: let $auctionFrame = jQuery(`<iframe srcdoc='${auctionFrameCode}'></iframe>`);
// OR: let $auctionFrame = jQuery(`<iframe src='about:blank'></iframe>`);

$("body").append($auctionFrame);

const blob = new Blob([auctionFrameCode], {type: 'text/html'});
$auctionFrame.attr('src', window.URL.createObjectURL(blob));

In renderingManager in line 125 it would eventually fail, because publisherDomain would have a blob: or about: prepend/protocol.

Expected behavior To be conceous of non-standard protocols and/or origins, and, maybe, replace targetOrigin to "*" in such cases? Not sure.

patmmccann commented 2 years ago

@Zer0Divis0r could you expand a bit on the use case here? Why wound UC be loaded in an iframe with srcdoc attribute or src=about:blank?

dgirardi commented 2 years ago

This should be an issue only when Prebid (not the creative) lives in an origin-less frame. I don't think just broadcasting the message to '*' is a good idea because it opens up some attacks (a malicious frame could read the message and, among other things, reply with a counterfeit ad - which can include any js code that the creative would run).

To support this use case, we could change the flow to:

  1. Prebid generates an additional nonce for each bid (let's call it adToken), which is passed to the ad server via targeting keys (in the same way adId is now).
  2. If the origin (pubUrl) is not available, creative sends request to '*', using adToken instead of adId as identifier.
  3. Prebid looks up the bid through adToken, and replies as it does now. Subsequent requests for the same adToken must be ignored.
  4. Creative discards replies whose adId does not match the one sent through targeting.

This should be backwards compatible and lock out actors that are not in possession of a valid adToken.

Zer0Divis0r commented 1 year ago

@Zer0Divis0r could you expand a bit on the use case here? Why wound UC be loaded in an iframe with srcdoc attribute or src=about:blank?

The use case is implementation of ad stack without adserver, and the container creative frames are created manually. This is very similar to the basic implementation, but with sandboxed frames.