Problem
We are an oEmbed provider to embed.ly which is integrated at medium.com to display widgets in articles. Embed.ly provides an height control API, which lets the iFrame change its size from the inside. This has been working, and still works in all browsers but Safari. Which now throws an error:
SecurityError: Blocked a frame with origin "https://medium.com" from accessing a cross-origin frame. Protocols, domains, and ports must match.
See an example here: https://medium.com/climateaction/its-time-to-challenge-instagrams-climate-footprint-e15c67bc2b7c
Update 2019-07-10
medium.com apparently changed something. Now:
- The described bug doesn't occur when opening the link directly * yaeeehi *
- It still occurs when coming from an overview page and clicking on an article * buuhhhh *
- There is a new bug, now embeds on custom domains don't work at all * arg *
Refused to display 'https://medium.com/media/c31b8b0f7cb609aaf60d13f46e3777bf' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
- There is now a double scrollbar for embeds in Windows/Mac Mojave/... + Chrome/Safari/...
Detailed Description
The integration is as followed:
- The medium.com article integrates an medium.com/media/... iFrame:
<iframe data-width="620" data-height="500" width="350" height="282" data-src="/media/1389b69a290289ae20aedd68efce0d4b?postId=e15c67bc2b7c" data-media-id="1389b69a290289ae20aedd68efce0d4b" data-thumbnail="https://i.embed.ly/1/image?url=https%3A%2F%2Fposixion.com%2Fimages%2Flogo.jpg&key=a19fcc184b9711e1b4764040d3dc5c07" class="progressiveMedia-iframe js-progressiveMedia-iframe" allowfullscreen="" frameborder="0" src="/media/1389b69a290289ae20aedd68efce0d4b?postId=e15c67bc2b7c">
</iframe>
This again integrates an embedly.com/widgets/... iFrame which loads our site.
We call window.parent.postMessage which reaches the medium.com iFrame sucessfully and the notifyResize function is called:
function notifyResize(height) {
height = height ? height : document.documentElement.offsetHeight;
var resized = false;
if (window.donkey && donkey.resize)
{donkey.resize(height); resized = true;}
if (parent && parent._resizeIframe)
{var obj = {iframe: window.frameElement, height: height}; parent._resizeIframe(obj); resized = true;}
if (window.location && window.location.hash === "#amp=1" && window.parent && window.parent.postMessage)
{window.parent.postMessage({sentinel: "amp", type: "embed-size", height: height}, "*");}
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize)
{window.webkit.messageHandlers.resize.postMessage(height); resized = true;}
return resized;
}
This breakes at parent._resizeIframe - which is weird, since the iFrame contents comes from https://medium.com and tries to access the parent which is also https://medium.com. Any thoughts on this?
Simulation
I tried replicating the error in my environment, but it works:
- Simulated medium.com article to: https://test.posixion.com/tests/medium.html
- Simulated iFrame to: https://test.posixion.com/tests/medium-embed.html
- Left embedly integration as is
Clue 1: content-security-policy
Maybe it is related to the content-security-policy of medium.com:
default-src 'self';
connect-src https://localhost https://*.instapaper.com https://*.stripe.com https://glyph.medium.com https://*.paypal.com https://getpocket.com https://medium.com https://*.medium.com https://*.medium.com https://medium.com https://*.medium.com https://*.algolia.net https://cdn-static-1.medium.com https://dnqgz544uhbo8.cloudfront.net https://cdn-videos-1.medium.com https://cdn-audio-1.medium.com https://*.lightstep.com https://*.branch.io https://app.zencoder.com 'self';
font-src data: https://*.amazonaws.com https://*.medium.com https://glyph.medium.com https://medium.com https://*.gstatic.com https://dnqgz544uhbo8.cloudfront.net https://use.typekit.net https://cdn-static-1.medium.com 'self';
frame-src chromenull: https: webviewprogressproxy: medium: 'self';
img-src blob: data: https: 'self';
media-src https://*.cdn.vine.co https://d1fcbxp97j4nb2.cloudfront.net https://d262ilb51hltx0.cloudfront.net https://*.medium.com https://gomiro.medium.com https://miro.medium.com https://pbs.twimg.com 'self' blob:;
object-src 'self';
script-src 'unsafe-eval' 'unsafe-inline' about: https: 'self';
style-src 'unsafe-inline' data: https: 'self';
report-uri https://csp.medium.com
But there is no matching report-uri call.
Clue 2: missing source
Interesting is also that the iFrame source: https://medium.com/media/1389b69a290289ae20aedd68efce0d4b?postId=e15c67bc2b7c does not appear in the webdeveloper network tab!? But it is still selectable as a page in the console.