Search code examples
htmlheadercontent-security-policy

How to create a Content Security Policy to allow a website to work inside an iframe


I need a third party website to operate inside an iframe in my website. The third party website works perfectly in the iframe in FireFox. In Chrome, for some reason, users are only allowed to login, thereafter any link they click on takes them back to the login page (which is the default page for the iframe).

So I looked for a solution and it seems I need to create a Content Security Policy. I've never worked with Content Security Policies before, so I'm not sure how to go about it.

I came across a post with a meta tag example of which I tried several variations of, but no matter how I try it, in Chrome, the page wouldn't even load in the iframe.

<html>
<head>
<title>Student Portal</title>
<link rel="shortcut icon" href="favicon.ico">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://<third party site>; img-src https://*; child-src 'self' https://<third party site>; script-src 'self' https://<third party site>; style-src 'self' https://<third party site>;" />
</head>
<body>
<!-- rest of my code -->
</body>
</html>

I've also tried the <embed> element instead, but get same results.

Is there another way of creating a Content Security Policy, or perhaps a whole other solution?

Any assistance will be appreciated


Solution

  • Content-Security-Policy will not solve your issue

    Content-Security-Policy (CSP) can only restrict what happens in a web page and block behavior that is open by default.

    Most probably problems - SameSite or Sec-fetch headers

    The most probable causes for the problem that you described of the site allowing the framing, but blocking the login:

    Option 1: SameSite Cookies Default

    If the site is not setting the login cookie with the SameSite parameter explicitly - that could be the issue. Firefox defaults cookies to the less secure SameSite=None. Chrome defaults cookies to the more secure SameSite=Lax (kind of).

    The Lax cookie could end up being discarded from the framed request (as it could be a form of Clickjacking / CSRF)

    Option 2: Site has a server side handler for Fetch metadata request headers

    The site may be blocking on the server-side based on context. These features are only supported in the recently released Firefox 90, but have been in Chrome for a while. If you are using Firefox 90 and you see the Sec-Fetch headers in the requests to that site, and the flow works fine, then this is not the issue. If it broke in FF when you upgrade to V90 - similar to Chrome: Your issue is a handler to one of these:

    Sec-Fetch-Site
    Sec-Fetch-Mode
    Sec-Fetch-User
    Sec-Fetch-Dest
    

    Option 3: Something else?

    Share more info on the case / site and I'll suggest more options.

    Related: CSP Usage Example

    By default you can frame any other site in your site. It is the open nature of the web. However you can block iframes from your site with CSP:

    Content-Security-Policy:frame-src 'none';

    Likewise, a site can refuse to get framed with CSP by setting the (better) equivalent of X-frame-options:deny:

    Content-Security-Policy:frame-ancestors 'none';

    P.S. don't use CSP meta tags

    Serving the CSP through an html meta header is considered legacy and has some drawbacks with multiple browser edge-cases. Setting the CSP via the HTTP headers of the request only.

    More info on <meta> bugs