iFrame Sandbox with Content Security Policy
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....
If expression matches the
host-source
grammar:
If url’s host is
null
, return "Does Not Match
".If expression does not have a
scheme-part
, then return "Does Not Match
" unless one of the following conditions is met:
- origin’s scheme is url’s scheme
- origin’s scheme is "
http
", and url’s scheme one of "https
", "ws
", or "wss
".- origin’s scheme is "
https
", and url’s scheme is "wss
".
In the given example:
- origin's scheme is
null
(because of the use ofsandbox
withoutallow-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.