iFrame Sandbox with Content Security Policy

14,792

When you use a sandboxed page with a unique origin, you can't put a host without scheme in the CSP, that's why the policy is violated. Use script-src https://example.com or script-src http://example.com or even script-src https://example.com http://example.com, and the CSP will correctly be relaxed (note that the CSP is whitelist-based, by default most things are disallowed).


As the grammar from the CSP specification shows, the scheme in a CSP directive is optional:

; Schemes: "https:" / "custom-scheme:" / "another.custom-scheme:"
scheme-source = scheme-part ":"

; Hosts: "example.com" / "*.example.com" / "https://*.example.com:12/path/to/file.js"
host-source = [ scheme-part "://" ] host-part [ port-part ] [ path-part ]
scheme-part = scheme
              ; scheme is defined in section 3.1 of RFC 3986.
host-part   = "*" / [ "*." ] 1*host-char *( "." 1*host-char )
host-char   = ALPHA / DIGIT / "-"
port-part   = ":" ( 1*DIGIT / "*" )
path-part   = path-abempty
              ; path-abempty is defined in section 3.3 of RFC 3986.

But a sandboxed frame without the allow-same-origin token will have a null origin, and the URL matching algorithm does not allow scheme-less directives to match (relevant parts of the algorithm shown below):

6.6.1.6. Does url match expression in origin with redirect count?

Given a URL (url), a source expression (expression), an origin (origin), and a number (redirect count), this algorithm returns "Matches" if url matches expression, and "Does Not Match" otherwise.

...

  1. If expression matches the host-source grammar:

    1. If url’s host is null, return "Does Not Match".

    2. If expression does not have a scheme-part, then return "Does Not Match" unless one of the following conditions is met:

      1. origin’s scheme is url’s scheme
      2. origin’s scheme is "http", and url’s scheme one of "https", "ws", or "wss".
      3. origin’s scheme is "https", and url’s scheme is "wss".

In the given example:

  • origin's scheme is null (because of the use of sandbox without allow-same-origin).
  • url is http://example.com/script.js

The null origin's scheme does not match any of the last three cases, so the host name without scheme won't match any URL, and therefore the policy is violated.

Share:
14,792
jhleath
Author by

jhleath

Updated on June 12, 2022

Comments

  • jhleath
    jhleath almost 2 years

    I assume that this is just a simple misunderstanding of the spec. However, I'm having an issue with including scripts in iFrames protected by sandboxing. Specifically, the code I am dealing with is below.

    In top.html:

    <iframe src="framed.html" sandbox="allow-scripts"></iframe>
    

    In framed.html

    ...
    <head>
      <meta http-equiv="Content-Security-Policy" content="script-src example.com">
      <script src="http://example.com/script.js"></script>
    </head>
    ...
    

    When running this file in Chrome, it gives me the error:

    Refused to load the script 'http://example.com/script.js' because it violates the following Content Security Policy directive: "script-src localhost:9000".

    Why is it blocking the script from loading? I know that without allow-same-origin, the iFrame gets a completely unique origin that is not equal to any other origin. Therefore, script-src 'self' wouldn't work. However, I am trying to load the script from an origin explicitly called for in the CSP. Thoughts?

    Update: Created JSFiddle to showcase the issue.

  • jhleath
    jhleath almost 10 years
    Wow - that was incredibly silly of me. Thanks so much for the help. I think I was just going off of examples on MDN that showed the CSP without the scheme.
  • Rob W
    Rob W almost 10 years
    @huntaub On a second thought, I am wrong. The specification allows omission of the scheme (because it is within square brackets, which means that the token is optional). It seems more likely that the specification is not correctly adhered to, i.e. a browser bug. Could you unaccept my answer? Then I will delete it.
  • jhleath
    jhleath almost 10 years
    Yeah - I can unaccept your answer, although - I wouldn't delete it just yet. It is useful for figuring out why this doesn't work.
  • jhleath
    jhleath almost 10 years
    Do you think that I should submit a bug report to Chromium?
  • Rob W
    Rob W almost 10 years
    First check whether it is really a bug, and not an oversight from one of us, then create a minimal test case, then post it at crbug.com/new.
  • mikemaccana
    mikemaccana about 6 years
    @RobW if your answer is incorrect re: scheme, can you edit or remove it?
  • Rob W
    Rob W about 6 years
    @mikemaccana The conclusion was correct, but the explanation was missing. I have corrected the explanation, please take another look.