Summary:
Site at https://localhost:3000
, with Content-Security-Policy
value of default-src 'self' 'unsafe-inline' https://localhost:3001/https_index.html
contains iframe pointing at https://localhost:3001/index.html
. The contents of :3001/index.html
contain an <a href="mailto..."></a>
. Clicking that link fails: Refused to frame '' because it violates the following Content Security Policy directive...
. How can I change my CSP value to prevent this error; to open an new email in user's preferred email client (normal behavior of mailto
)? I am using Chrome1
Detail:
Similar but different than this question "mailto link not working within a frame chrome (over https) "
I think mine is not a duplicate because:
I cannot reproduce that bug, I see a console warning about mixed-content when I try to reproduce their steps:
Mixed Content: The page at 'https://localhost:3001/https_index.html' was loaded over HTTPS, but requested an insecure resource 'mailto:...'. This content should also be served over HTTPS.
My steps are specific; both my page & its iframe src are
https
, but the page itself is served with a specific and restrictiveContent-Security-Policy
(CSP
):app.use(csp({ directives: { defaultSrc: ["'self' 'unsafe-inline' https://localhost:3001/https_index.html"] } }));
Also the resulting error I can reproduce is different:
Refused to frame '' because it violates the following Content Security Policy directive: "default-src 'self' https://localhost:3001/https_index.html". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback.
- The accepted answers for the original questions will help me work around my CSP-specific issue, that is, if I add a
target="_top"
to the link, the email client opens without error:<a target="_top" href="mailto:...">email</a>
A similar fix works for another similar but different issue. However, this may1 sometimes open a new tab
So my question is specifically about the Content-Security-Policy
error (see above):
...Refused to frame '' because it violates the following Content Security Policy directive: ...
Notice it says frame ''
. The frame is identified as an empty string!
Normally if some resource violates CSP, the URL of the resource is identified; i.e.
Refused to laod the script 'http://evil.com/evil.js'...
And if the CSP
-violating URL is identified + provided I can use it; add it to my CSP
value for default-src
:
`app.use(csp({
directives: {
defaultSrc: ["http://evil.com/evil.js 'self' 'unsafe-inline' https://localhost:3001/https_index.html"]
}
}));`
But can I allow an exception for an href
value? Specifically for mailto
? I tried wildcards like mailto*
, but:
The source list for Content Security Policy directive 'default-src' contains an invalid source: 'mailto*'.
And I wonder if any wildcard would work anyway; does Chrome really consider the href="mailto..."
frame as an empty string? I suppose so, since it's not a URL per se; Chrome "wants" to launch an external application (i.e. Outlook) in the context of the iframe; who is bound to the CSP rules of its parent page...
Footnotes:
- Chrome displays the above errors in CSP or sandbox cases. Internet Explorer doesn't complain about an
iframes
href, despite the value ofCSP
. Internet Explorer also doesn't have the "new tab" problem, despite the value ofsandbox
. IE 11.1914 will just give message:
The fix of using
target="_top"
may open a new tab , if you'vesandbox
ed your iframe! (sandbox
is different thanCSP
). I don't like the new tab. Chrome gave me this error...Unsafe JavaScript attempt to initiate navigation for frame with URL 'http://localhost:3000/' from frame with URL 'https://localhost:3001/index.html'. The frame attempting navigation of the top-level window is sandboxed, but the flag of 'allow-top-navigation' or 'allow-top-navigation-by-user-activation' is not set.
... but opened a new tab, as well as the Outlook email client...
I did what the error suggested; modifying the value of the iframe
sandbox
attribute:
sandbox="allow-top-navigation allow-same-origin ..."
, and the mailto link worked (as before), but did not open an excessive new tab. Great!