Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[csp-embedded-enforcement] Buggy behavior with multiple nested frames #558

Closed
qabandi opened this issue Jul 25, 2022 · 1 comment
Closed

Comments

@qabandi
Copy link

qabandi commented Jul 25, 2022

Originally pointed out at: https://bugs.chromium.org/p/chromium/issues/detail?id=1263288#c10

@antosart I couldn't find an existing case file so am creating one here.

Take the following set up:

from: http://trusted.test/grandparent.php ===>(A)

header("Content-Security-Policy:script-src 'strict-dynamic' 'nonce-grandparent'");
?>
<html>
    <head>
        <title>grandfather</title>
    <head>
<body>

<iframe src="http://untrusted.test/parent.php" csp="script-src 'strict-dynamic' 'nonce-required'" style="width:60%;height:60%;"></iframe>
</body>
</html>

from: http://untrusted.test/parent.php ===>(B)

header("Content-Security-Policy:script-src 'strict-dynamic' 'nonce-parent'");
?>
<html>
    <head>
        <title>parent</title>
    <head>
<body>
    <div id="qdiv"></div>
<script nonce="parent">
qdiv.innerText="hello from parent"

</script>
<iframe id="qiframe" src="./child.php"></iframe>
</body>
</html>

from: http://untrusted.test/child.php ===>(C)

header("Content-Security-Policy:script-src 'strict-dynamic' 'nonce-child'");
?>
<html>
    <head>
        <title>child</title>
    <head>
<body>
<div id="qdiv"></div>
<script nonce="child">
qdiv.innerText="hello frodm child"
</script>

</body>
</html>

Observations:

When navigating to A it will attempt to embed cross origin B with the following CSPEE request header:
Sec-Required-CSP: script-src 'strict-dynamic' 'nonce-required'
Since A and B are cross-origin, 'nonce-required' acts sort of like a hint that A expects B to implement some form of nonce.

And since B responds with the following CSP:
Content-Security-Policy:script-src 'strict-dynamic' 'nonce-parent'"
A is satisfied with the requirement and allows B to load in the iframe.

Once B loads, it attempts to load C and sends the following CSPEE request header:
Sec-Required-CSP: script-src 'strict-dynamic' 'nonce-required'
But since B and C are same-origin, despite C sending back a seemingly compliant CSP:
Content-Security-Policy:script-src 'strict-dynamic' 'nonce-child'

B will still allow C to load but C is unable to run javascript despite being 'blessed' by a proper nonce that it defined, which is 'child'. This is what I understand per https://bugs.chromium.org/p/chromium/issues/detail?id=1263288#c3

Solution

The main workaround here is to simply serve C from a cross-origin (as it relates to B) URL.
The problem is that this may not work as a solution for all scenarios.

Problems
Assuming we must keep C same origin as B:

No 'nonce' value works when put into the script of C (so long as C is setting its own CSP). I tried setting C's nonce to: 'grandparent', 'parent', 'required' and 'child' and none of them work which seems odd.

If I remove the CSP response from C, the only nonce value that works is: 'required' which remember, will never be a real nonce and is only used in CSPEE to hint to embeddee that some nonce should be used. Also the fact we are removing CSP means C can now be loaded in normal main frame and unless the server side is checking for this it will serve it without a CSP which is unsecure (assuming they try to fix this bug that way)

I expected that C would still be considered cross-origin if the iframe[sandbox] attribute was present. That is not the case despite technically C frame is considered 'cross-origin' from B perspective when B tries to access sandboxed C js window.

Proposal

Allow same-origin CSPEE to behave like cross-origin IFF:

  1. B embeds same origin C with another iframe[csp] attribute of its own
  2. (and/or) B embeds same origin C with iframe[sandbox] attribute set
@antosart
Copy link
Member

antosart commented Aug 5, 2022

I moved the issue to webappsec-cspee, see w3c/webappsec-cspee#26

@antosart antosart closed this as completed Aug 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants