Closed Bug 1888198 Opened 1 year ago Closed 1 year ago

CSP Bypass via iFrame Scripting

Categories

(Core :: DOM: Security, defect)

defect

Tracking

()

RESOLVED INVALID

People

(Reporter: telavivkeller, Unassigned)

Details

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

Attachments

(1 file)

Attached file PROOF_OF_CONCEPT.zip

Content Security Policy (CSP) serves as a security mechanism for web applications, primarily aimed at mitigating cross-site scripting (XSS) attacks. However, scripting in iFrames is still allowed, even scripting on CSP enforced same-origin parents/children.

This vulnerability stems from the ability of iframes with the same origin as the parent page to execute scripts within the parent's context, irrespective of CSP blockings. The technical process involves:

  • Embedding an iframe within the parent page, sharing the same origin.
  • Loading scripts within the iframe that would typically be blocked by CSP if loaded directly onto the parent page.
  • Exploiting the execution context of the parent page to carry out malicious actions through scripts within the iframe.

The exploitation of CSP bypass via iframes can have significant repercussions:

  • XSS Attacks: Malicious scripts executed within the parent page's context can lead to data theft, session hijacking, or unauthorized access to sensitive information.
  • Content Injection: Attackers can inject malicious content into the parent page, such as phishing forms or deceptive advertisements, eroding user trust and damaging the application's integrity.
  • Data Exfiltration: By leveraging CSP bypass, attackers may exfiltrate sensitive user data accessible within the parent page to external servers, resulting in privacy violations and regulatory compliance issues.

For the PoC, host it at localhost:3000 and visit index.html. From there, notice that a variable declared in init.js for index.html is accessible from iframe.html, despite the anti-scripting CSP in place.

Flags: sec-bounty?

Keep in mind this also works for frame children (this is probably a bigger impact), see

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test #2</title>
</head>
<body>
    <iframe src="index.html"></iframe>
    <script>window.onload = () => { alert(window.frames[0].secret)}</script>
    </body>
</html>

That's not what CSP blocks. CSP blocks the parsing of script (allowed by unsafe-inline) and the evaling of strings into script (allowed by unsafe-eval), but it does not block the actions of script that has already been allowed to run. The same origin policy allows scripting across frames, and CSP does not block that (unless you use the CSP or iframe "sandbox")

Group: firefox-core-security
Status: UNCONFIRMED → RESOLVED
Closed: 1 year ago
Component: Security → DOM: Security
Product: Firefox → Core
Resolution: --- → INVALID

Scripting inside an iFrame is OK, but the iFrame shouldn't be able to script in the context of the CSP enforced parent/child.
If a window has scripting disallowed, a same-origin frame shouldn't be allowed to script in it.

The behavior that I am specifically concerned about is that the iFrame, while allowed to script, should not be allowed to script on the CSP-blocked parent window.

Examples from DevTools

From Parent

window.eval("window.secret");
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src http://localhost:3000/init.js".

From Child

window.eval("window.top.secret")
"Nooo, don't read me!"
window.top.eval("window.secret")
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src http://localhost:3000/init.js".

As you can see, window.top.* can be accessed and executed from the child frame. Anything window.eval can do can be done, except for eval itself.

The same way that <iframe srcdoc="<script>console.log(window.top.secret)</script>"></iframe> is blocked (via unsafe-inline), so should an iFrame to same-source script be blocked from accessing the parent.

I can see the model you're describing, but that's not what the spec says and browsers are currently compatible on this behavior

The two windows are same-origin so DOM access should be granted according to the same-origin policy. If you want to prevent access from either of the two sides, you should make use of <iframe sandbox> or the sandbox CSP attribute.

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: