Is it possible to use iFrames to embed other asset canisters?

Short version:
If you are open links like https://CANISTER_ID.ic0.app inside IFrame of another app https://PARENT_CANISTER_ID.ic0.app, then boundary nodes adds a response header X-Frame-Origin: Deny and IFrame does not open. Is is sad :frowning:
Maybe make adding this header customizable?

Why?
I am checking to see if it is possible to open a front-end canister link in the IFrame (in iframe in iframe) and I ran into a problem: the front-end canisters work in the IFrame only when they are loaded from https://CANISTER_ID.raw.ic0.app.

Note: In simple terms raw means that the assets will be loaded “as is” without any data certification checks in the browser. And as it was said in other topics: in this case, data checks must be performed by itself

Point 1.
If you first open the link without raw (https://CANISTER_ID.ic0.app) in another tab (“warm up”), then this link starts to open in the IFrame of https://PARENT_CANISTER_ID.ic0.app.
This is because the service worker is already loaded, the service worker checks the certificates. At the next request for https://CANISTER_ID.ic0.app, the X-Frame-Origin: Deny header is absent (which does not interfere with the display in the iframe)

Point 2.
I managed to get some of the service worker code for checking certificates from devtools, but I suspect that this is not the whole code. If you have to use raw domain, then it would be nice to get the source code of the worker to independently connect to my canister.

Point 3.
Perhaps the header X-Frame-Origin: Deny should save from click-jacking, but that’s not entirely true. Because it turns out that if you use raw links, then the IFrame opens and it loses its meaning. And if we take into “point 1”, then it becomes interesting: why was this protection used at all and what does it protect from?

About clickjacking:
If the certificates are verified (without raw urls), no malicious code will get to the canister from the middle-node or malicious node. This means that the responsibility lies with the developers of the canister. They must make sure that no malicious code appears on their page. After all, you can’t slip a script from the parent window into the iframe, since these are different domains and the browser will block any manipulation with the IFrame. At the same time, raw links works quietly in the IFrame, and without checking the certificates.
If I’m wrong - correct me please

Eventually:
let’s give the asset canister minimal ability to control the headers. For example, if the canister adds X-Frame-ORIGIN: SAMEDOMAIN or X-Frame-ORIGIN: "" to response, then the boundary nodes will not override that headers.
This will open up great opportunities for integrating canisters with each other.

2 Likes

Hey there @bjoern

You’ve once posted this message:

From which it seems like there was no initial intent to set the X-Frame-Origin header to Deny and this is some kind of misunderstanding within the team. Did you guys figured it out? Could you please ping someone who can elaborate on that?

It looks like clickjacking can still be performed, judging by this:

Thanks in advance!

1 Like

This header is added for “Internet Computer Content Validation Bootstrap” page, which is already registering a worker to verify certificates. This page is pre-loaded before loading the main page. Is it possible to disable or mitigate this header?
I checked many cases with the opening of .raw. urls and made sure that it will not work to connect my certificate verification. Since the checks and JS files are loaded from the untrusted .raw. zone, and if the node is compromised, it may return the entry point with the compromised check code.
Example:

  • open https://PARENT_CANISTER_ID.ic0.app
  • this page opens IFrame with url https://CANISTER_ID.raw.ic0.app. That is only way to open IFrame now.
  • https://CANISTER_ID.raw.ic0.app may be already compromised
  • https://CANISTER_ID.raw.ic0.app loads and registers service-worker for certification and another check. And reloads page (known technical nuance)
  • If the node is malicious, the links to JS or the content of the service worker could also be changed.
  • So how can I add checks safely for .raw. urls?

Unfortunately, there is currently no way to display canister content inside iframes safely from malicious nodes. But this is the only way to implement my task and it would be nice to understand what really caused these restrictions

1 Like

Hi 3cL1p5e7,

as written in the other thread (Integrate Internet Identity within iFrame - #7 by frederikrothenberger) we definitely plan to give developers more control over the headers of their canisters HTTP responses (including the possibility to make pages embeddable within iFrames). We are just not there yet (as there are some security issues to solve).

I will update this thread once the feature is available.

Best regards,
Frederik

4 Likes

Hi Frederik :slight_smile:
Thank you so much for your reply! :heart:
Looking forward to it

Wondering if there is any update on this?

V2 certification lets you certify headers, so I’d expect maybe it is better now. @NathanosDev can likely point you to where you can set this up.

I’m not sure about the dfx asset canister, but since embedding OC and other dapps seems to be solved with an iframe, I would say it’s probably supported.

As for Juno, it’s definitely supported, of course.

{
  "satellite": {
    "id": "qsgjb-riaaa-aaaaa-aaaga-cai",
    "source": "dist",
    "storage": {
      "iframe": "allow-any"
    }
  }
}

There’s still some configuration on the boundary nodes to add X-Frame-Options: DENY to the response headers: ic/ic-os/boundary-guestos/rootfs/etc/nginx/conf.d/000-nginx-global.conf at b9e167bb8b2f524e035654d002bc4c91a5029def · dfinity/ic · GitHub.

I would’ve thought this is applied to every response, but @peterparker’s comment suggests otherwise.

Maybe @rbirkner could help clarify how this is behaving.

For example, if Rüdi or anyone else would want to debug something, icdraw (hosted through Juno) is available through an iframe on Windoge98.

1 Like

It should be possible to embed canisters within an iFrame. That nginx configuration that @NathanosDev is not “effective” (nginx has some weird behavior that if you add a header at some point, but keep modifying other headers, previously added headers disappear).

You can verify that by opening some IC site and looking at the headers in the “network” pane of the developer tools. For example, https://2fdjx-hqaaa-aaaam-abria-cai.icp0.io/ has no such header set. However, there are dapps that explicitly set that headers (e.g., Internet Identity, the NNS dapp, or the internetcomputer.org site).

1 Like

Worth to note given the above discussion that denying iframe is the default behavior of Juno.