Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 2798413

Browse files
author
Christoph Kerschbaumer
committed
Bug 1668071: Use Principal URI instead of document URI when doing CSP frame-ancestors checks so origins which inherit the security context work correctly. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D93214
1 parent 954aff6 commit 2798413

5 files changed

Lines changed: 101 additions & 18 deletions

dom/security/nsCSPContext.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,7 @@ nsCSPContext::PermitsAncestry(nsILoadInfo* aLoadInfo,
15501550
nsCOMPtr<nsIURI> uriClone;
15511551

15521552
while (ctx) {
1553-
nsCOMPtr<nsIURI> currentURI;
1553+
nsCOMPtr<nsIPrincipal> currentPrincipal;
15541554
// Generally permitsAncestry is consulted from within the
15551555
// DocumentLoadListener in the parent process. For loads of type object
15561556
// and embed it's called from the Document in the content process.
@@ -1559,28 +1559,37 @@ nsCSPContext::PermitsAncestry(nsILoadInfo* aLoadInfo,
15591559
if (XRE_IsParentProcess()) {
15601560
WindowGlobalParent* window = ctx->Canonical()->GetCurrentWindowGlobal();
15611561
if (window) {
1562-
currentURI = window->GetDocumentURI();
1562+
// Using the URI of the Principal and not the document because e.g.
1563+
// about:blank inherits the principal and hence the URI of the
1564+
// document does not reflect the security context of the document.
1565+
currentPrincipal = window->DocumentPrincipal();
15631566
}
15641567
} else if (nsPIDOMWindowOuter* windowOuter = ctx->GetDOMWindow()) {
1565-
currentURI = windowOuter->GetDocumentURI();
1568+
currentPrincipal = nsGlobalWindowOuter::Cast(windowOuter)->GetPrincipal();
15661569
}
15671570

1568-
if (currentURI) {
1569-
nsAutoCString spec;
1570-
currentURI->GetSpec(spec);
1571-
// delete the userpass from the URI.
1572-
rv = NS_MutateURI(currentURI)
1573-
.SetRef(""_ns)
1574-
.SetUserPass(""_ns)
1575-
.Finalize(uriClone);
1576-
1577-
// If setUserPass fails for some reason, just return a clone of the
1578-
// current URI
1579-
if (NS_FAILED(rv)) {
1580-
rv = NS_GetURIWithoutRef(currentURI, getter_AddRefs(uriClone));
1581-
NS_ENSURE_SUCCESS(rv, rv);
1571+
if (currentPrincipal) {
1572+
nsCOMPtr<nsIURI> currentURI;
1573+
auto* currentBasePrincipal = BasePrincipal::Cast(currentPrincipal);
1574+
currentBasePrincipal->GetURI(getter_AddRefs(currentURI));
1575+
1576+
if (currentURI) {
1577+
nsAutoCString spec;
1578+
currentURI->GetSpec(spec);
1579+
// delete the userpass from the URI.
1580+
rv = NS_MutateURI(currentURI)
1581+
.SetRef(""_ns)
1582+
.SetUserPass(""_ns)
1583+
.Finalize(uriClone);
1584+
1585+
// If setUserPass fails for some reason, just return a clone of the
1586+
// current URI
1587+
if (NS_FAILED(rv)) {
1588+
rv = NS_GetURIWithoutRef(currentURI, getter_AddRefs(uriClone));
1589+
NS_ENSURE_SUCCESS(rv, rv);
1590+
}
1591+
ancestorsArray.AppendElement(uriClone);
15821592
}
1583-
ancestorsArray.AppendElement(uriClone);
15841593
}
15851594
ctx = ctx->GetParent();
15861595
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE HTML>
2+
<html>
3+
<head>
4+
<title>Helper file for Bug 1668071 - CSP frame-ancestors in about:blank</title>
5+
</head>
6+
<body>
7+
CSP frame-ancestors in about:blank
8+
</body>
9+
</html>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cache-Control: no-cache
2+
Content-Security-Policy: frame-ancestors http://mochi.test:8888

dom/security/test/csp/mochitest.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,3 +433,7 @@ support-files =
433433
file_upgrade_insecure_navigation_redirect_same_origin.html
434434
file_upgrade_insecure_navigation_redirect_cross_origin.html
435435
[test_csp_style_src_empty_hash.html]
436+
[test_csp_frame_ancestors_about_blank.html]
437+
support-files =
438+
file_csp_frame_ancestors_about_blank.html
439+
file_csp_frame_ancestors_about_blank.html^headers^
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!DOCTYPE HTML>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Bug 1668071 - CSP frame-ancestors in about:blank</title>
6+
<script src="/tests/SimpleTest/SimpleTest.js"></script>
7+
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
8+
</head>
9+
<body>
10+
11+
<script class="testbody" type="text/javascript">
12+
13+
/* Description of the test:
14+
* We dynamically load an about:blank iframe which then loads a testframe
15+
* including a CSP frame-ancestors directive which matches the including
16+
* security context. We make sure that we not incorrectly block on
17+
* about:blank which should inherit the security context.
18+
*/
19+
20+
SimpleTest.waitForExplicitFinish();
21+
22+
let aboutBlankFrame = document.createElement("iframe");
23+
document.body.appendChild(aboutBlankFrame);
24+
25+
aboutBlankFrame.onload = function() {
26+
ok(true, "aboutBlankFrame onload should fire");
27+
let aboutBlankDoc = aboutBlankFrame.contentDocument;
28+
is(aboutBlankDoc.documentURI, "about:blank",
29+
"sanity: aboutBlankFrame URI should be about:blank");
30+
31+
let testframe = aboutBlankDoc.createElement("iframe");
32+
aboutBlankDoc.body.appendChild(testframe);
33+
testframe.onload = function() {
34+
ok(true, "testframe onload should fire");
35+
let testDoc = SpecialPowers.wrap(testframe.contentDocument);
36+
ok(testDoc.documentURI.endsWith("file_csp_frame_ancestors_about_blank.html"),
37+
"sanity: document in testframe should be the testfile");
38+
39+
let cspJSON = testDoc.cspJSON;
40+
ok(cspJSON.includes("frame-ancestors"), "found frame-ancestors directive");
41+
ok(cspJSON.includes("http://mochi.test:8888"), "found frame-ancestors value");
42+
43+
SimpleTest.finish();
44+
}
45+
46+
testframe.onerror = function() {
47+
ok(false, "testframe onerror should not fire");
48+
}
49+
testframe.src = "file_csp_frame_ancestors_about_blank.html";
50+
}
51+
52+
aboutBlankFrame.onerror = function() {
53+
ok(false, "aboutBlankFrame onerror should not be called");
54+
}
55+
aboutBlankFrame.src = "about:blank";
56+
57+
</script>
58+
</body>
59+
</html>

0 commit comments

Comments
 (0)