Embeds can be more secure and potentially more performant if wrapped in iframe with srcdoc #1626
Labels
[Plugin] Embed Optimizer
Issues for the Embed Optimizer plugin (formerly Auto Sizes)
[Type] Enhancement
A suggestion for improvement of an existing feature
I was just discussing with @adamsilverstein the behavior of how oEmbeds are inserted into a page. In particular, when an oEmbed has a type of
rich
(orvideo
) the oEmbed markup may not just contain anIFRAME
but it may include aSCRIPT
tag as well, which can be seen in Twitter embeds.The problem here is that third-party JavaScript is being (intentionally) injected into the page. If the embed provider is compromised, they could do XSS attacks on site visitors (as well as do nefarious tracking). To help mitigate this, WordPress core's
wp_filter_oembed_result()
function has an allowlist check: "Don't modify the HTML for trusted providers." This handles the case of untrusted oEmbed providers, but again, even trusted providers could end up being malicious.This might also facilitate the use of Strict CSP on pages with embeds without having to indiscriminately add
nonce
attributes to theSCRIPT
tags.Adam noted how Drupal has a Security section in its Media settings screen for oEmbeds:
The oEmbed Security Considerations are:
By wrapping the oEmbed HTML in an
IFRAME
(likely wrapping anotherIFRAME
already in the embed markup) pointing to a cross-origin URL for a page contains that embed markup, then the cross-origin security policy will prevent any malicious markup from executing on the host page. This isn't really feasible for most WordPress sites which don't have an extra domain handy just for serving embeds (and perhaps it isn't so common for Drupal either since this doesn't seem to be enabled by default).There is an alternative now to
IFRAME
sandboxing using another domain, and that is in thesrcdoc
attribute paired with thesandbox
attribute. For example (Codepen):This results in the following being printed:
When the
allow-same-origin
token is supplied in thesandbox
attribute (or thesandbox
attribute is removed entirely), the cross-origin restriction is removed:Naturally, additional
sandbox
tokens would be required in embeds, in particularallow-top-navigation-by-user-activation
. Additionally, the markup inside thesrcdoc
would need to also include aResizeObserver
which would send messages to the host page to resize theIFRAME
when the content size is changed.Wrapping the embed markup in an
IFRAME
would have an additional benefit beyond security hardening in that it would improve the ability to lazy-load embeds. Every time a Tweet is embedded on a page, for example, it includes theBLOCKQUOTE
containing the fallback Tweet content as well as the TwitterSCRIPT
that turns that into an embed. If there is a Tweet in the initial viewport which does not get lazy-loaded, then theSCRIPT
loaded for that Tweet instance will then look for all other TweetBLOCKQUOTE
instances and construct them as well. So lazy-loading TwitterSCRIPT
tags currently has no effect at present. By wrapping each Tweet embed in anIFRAME
with asrcdoc
we can dynamically populate thatsrcdoc
attribute with the contents of the Tweet when it enters the viewport, thus ensuring each embed is lazy-loaded correctly. (There will surely be additional overhead for wrapping embeds in asrcdoc
IFRAME
but I imagine the pros outweigh the cons.)I'm not sure why Drupal doesn't just use
srcdoc
instead of the cross-originIFRAME
URL. Maybe it's becausesrcdoc
wasn't supported in IE11? Or maybe there's another security benefit I'm not aware of.The text was updated successfully, but these errors were encountered: