Search code examples
iframecontent-security-policy

Content-Security-Policy: which source of constraints is the strictest?


Context

I have this CSP on a page (in a vite react app):

frame-src http://localhost:3080; style-src 'self' 'unsafe-inline' http://localhost:3080

On the page, an iframe from http://localhost:3080 is embedded. I don't have control over that iframe as it is generated by a 3rd party app running in a container locally. The iframe's own CSP headers are similar to the following:

default-src 'none'; script-src 'self' https://maps.google.com https://accounts.google.com https://www.google-analytics.com 'sha256-xxxx=' 'sha256-xxxx=' 'sha256-xxxx='; child-src 'self' https://accounts.google.com; style-src 'self' 'nonce-xxxx' https://accounts.google.com; font-src *; img-src * 'self' data:; connect-src 'self' https://accounts.google.com service.us10.list-manage.com www.google-analytics.com https://service.example.com ; manifest-src 'self'; frame-ancestors 'none';

The problem

In the main vite app, when I try to adjust the height of the child iframe, I get this error in the browser:

Uncaught SecurityError: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "http://localhost:3000" from accessing a cross-origin frame.

also this error (which is interesting as I'm not directly doing anything with https://accounts.google.com):

Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'nonce-xxxx'   https://accounts.google.com". Either the 'unsafe-inline' keyword, a hash ('sha256-xxxx='), or a nonce ('nonce-...') is required to enable inline execution.

Question

Is there a CSP, given the above scenario, that the vite app can implement, that will allow the iframe's height to be updated, or is this an impossibility? I can't tell whether the code is wrong or if this is actually technically infeasible.


Solution

  • If you're running the 3rd party app on a different port to your main application, then you fall fowl of the cross-domain browser restrictions.

    The easy solution is to put a reverse proxy (Nginex) in front of both your app and the 3rd party app and server both from the same domain, port and protocol.