Rust, Linux, programming languages, type systems

MV3 Chrome extension with iframe, which embeds any site

I created manifest v3 Chrome/Chromium extension with <iframe>, which can host any site, even those, which set X-Frame-Options: deny.

Also, my extension contains many hacks for some real world sites.

So, this is the code: https://sr.ht/~safinaskar/blog-browser/ . The code is heavily commented.

And this is list of hacks:
– First of all, I remove X-Frame-Options header (obviously). It is set by many sites
– Also I remove Content-Security-Policy header. It prevents loading to <iframe>, too. https://paste.gg sets both X-Frame-Options and Content-Security-Policy
https://web.telegram.org can load itself to the top frame (window.top). So I put sandbox attribute on <iframe>
https://vk.com uses window.parent === window to check whether we are in <iframe>. So I fake window.parent for an <iframe>. (But I cannot fake window.top, because this is non-configurable property!)
– As I said previously, I set sandbox attribute. Unfortunately, this prevents an <iframe> from assigning to document.domain. And https://vk.com needs this! So I fake document.domain
– We hack around with window properties not only in <iframe> itself, but also in its own iframes, too

Tested with Chromium 121.

Here are related links:
https://stackoverflow.com/questions/74391398/mv3-declarativenetrequest-and-x-frame-options-deny (my extension is based on this code)
https://stackoverflow.com/a/69177790
https://github.com/MartinWie/Framer/
https://github.com/w3c/webextensions/issues/483

Note:
– These links suggest that you need to unregister service workers for embedded site. I didn't find this useful
– Also, these links suggest cleaning cache. This is outright harmful: https://web.telegram.org stops to show avatars after this
https://github.com/w3c/webextensions/issues/483 contains some warning about SameSite=Lax, SameSite=Strict and SameSite=None. It doesn't apply here, because we are in extension context

As you can see, my solution turned out to be very hacky. I'm not aware of any better solution. Also, some sites seem to share data (cookies, local storage, etc) with its domain/origin (for example, https://vk.com and https://web.telegram.org ), but some do not (such as https://youtube.com ).

There are some alternatives to my approach:
<fencedframe>. Looks like a very good solution. Unfortunately, it seems that using <fencedframe> requires to complete so-called enrollment process ( https://developer.mozilla.org/en-US/docs/Web/Privacy/Privacy_sandbox/Enrollment ). As well as I understand, I still can use <fencedframe> in local testing using some hacks, but I don't like this
– Controlled frame. ( https://wicg.github.io/controlled-frame/ ). Looks like even better solution. It seems it will not work in extension context, but will require so-called Isolated Web Application (IWA) context instead. Nonetheless I like this solution. Unfortunately, it seems that both controlled frames and IWAs themselves are in development stage. So, we will hope for the best

UPD 2024-07-21: See my big comment here: https://github.com/w3c/webextensions/issues/483#issuecomment-2241348613

Subscribe to this blog using button in the bottom of https://safinaskar.writeas.com/ or at Mastodon ( https://types.pl/@safinaskar ). I plan to write about formal methods, Rust and Linux.

You can reach me via email safinaskar@gmail.com .

Discuss at:
https://lobste.rs/s/raq7ce/mv3_chrome_extension_with_iframe_which
https://www.reddit.com/r/chrome_extensions/comments/1e8a95h/mv3_chrome_extension_with_iframe_which_embeds_any/
https://types.pl/@safinaskar/112821737773021199 (Mastodon)