mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 1582115
: Exempt pdf.js from being subject to CSP from page. r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D74614
This commit is contained in:
parent
edbe69232a
commit
2c610ecc1f
@ -76,8 +76,16 @@ bool subjectToCSP(nsIURI* aURI, nsContentPolicyType aContentType) {
|
||||
contentType == nsIContentPolicy::TYPE_STYLESHEET ||
|
||||
contentType == nsIContentPolicy::TYPE_DTD ||
|
||||
contentType == nsIContentPolicy::TYPE_XBL;
|
||||
if (aURI->SchemeIs("resource") && !isImgOrStyleOrDTDorXBL) {
|
||||
return true;
|
||||
if (aURI->SchemeIs("resource")) {
|
||||
nsAutoCString uriSpec;
|
||||
aURI->GetSpec(uriSpec);
|
||||
// Exempt pdf.js from being subject to a page's CSP.
|
||||
if (StringBeginsWith(uriSpec, NS_LITERAL_CSTRING("resource://pdf.js/"))) {
|
||||
return false;
|
||||
}
|
||||
if (!isImgOrStyleOrDTDorXBL) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (aURI->SchemeIs("chrome") && !isImgOrStyleOrDTDorXBL) {
|
||||
return true;
|
||||
@ -237,9 +245,9 @@ CSPService::AsyncOnChannelRedirect(nsIChannel* oldChannel,
|
||||
// context. In turn, we do not have an event target for policy violations.
|
||||
// Enforce the CSP check in the content process where we have that info.
|
||||
// We allow redirect checks to run for document loads via
|
||||
// DocumentLoadListener, since these are fully supported and we don't expose
|
||||
// the redirects to the content process. We can't do this for all request
|
||||
// types yet because we don't serialize nsICSPEventListener.
|
||||
// DocumentLoadListener, since these are fully supported and we don't
|
||||
// expose the redirects to the content process. We can't do this for all
|
||||
// request types yet because we don't serialize nsICSPEventListener.
|
||||
if (parentChannel && !docListener) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -323,9 +331,9 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
|
||||
|
||||
bool isPreload = nsContentUtils::IsPreloadType(policyType);
|
||||
|
||||
/* On redirect, if the content policy is a preload type, rejecting the preload
|
||||
* results in the load silently failing, so we convert preloads to the actual
|
||||
* type. See Bug 1219453.
|
||||
/* On redirect, if the content policy is a preload type, rejecting the
|
||||
* preload results in the load silently failing, so we convert preloads to
|
||||
* the actual type. See Bug 1219453.
|
||||
*/
|
||||
policyType =
|
||||
nsContentUtils::InternalContentPolicyTypeToExternalOrWorker(policyType);
|
||||
|
@ -17,3 +17,7 @@ support-files =
|
||||
support-files =
|
||||
file_csp_meta_uir.html
|
||||
[browser_manifest-src-override-default-src.js]
|
||||
[browser_pdfjs_not_subject_to_csp.js]
|
||||
support-files =
|
||||
dummy.pdf
|
||||
file_pdfjs_not_subject_to_csp.html
|
||||
|
48
dom/security/test/csp/browser_pdfjs_not_subject_to_csp.js
Normal file
48
dom/security/test/csp/browser_pdfjs_not_subject_to_csp.js
Normal file
@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
const TEST_PATH = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://example.com"
|
||||
);
|
||||
|
||||
add_task(async function() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["pdfjs.eventBusDispatchToDOM", true]],
|
||||
});
|
||||
await BrowserTestUtils.withNewTab(
|
||||
TEST_PATH + "file_pdfjs_not_subject_to_csp.html",
|
||||
async function(browser) {
|
||||
let pdfPromise = BrowserTestUtils.waitForContentEvent(
|
||||
browser,
|
||||
"documentloaded",
|
||||
false,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
await ContentTask.spawn(browser, {}, async function() {
|
||||
let pdfButton = content.document.getElementById("pdfButton");
|
||||
pdfButton.click();
|
||||
});
|
||||
|
||||
await pdfPromise;
|
||||
|
||||
await ContentTask.spawn(browser, {}, async function() {
|
||||
let pdfFrame = content.document.getElementById("pdfFrame");
|
||||
// 1) Sanity that we have loaded the PDF using a blob
|
||||
ok(pdfFrame.src.startsWith("blob:"), "it's a blob URL");
|
||||
|
||||
// 2) Ensure that the PDF has actually loaded
|
||||
ok(
|
||||
pdfFrame.contentDocument.querySelector("div#viewer"),
|
||||
"document content has viewer UI"
|
||||
);
|
||||
|
||||
// 3) Ensure we have the correct CSP attached
|
||||
let cspJSON = pdfFrame.contentDocument.cspJSON;
|
||||
ok(cspJSON.includes("script-src"), "found script-src directive");
|
||||
ok(cspJSON.includes("allowPDF"), "found script-src nonce value");
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
BIN
dom/security/test/csp/dummy.pdf
Normal file
BIN
dom/security/test/csp/dummy.pdf
Normal file
Binary file not shown.
21
dom/security/test/csp/file_pdfjs_not_subject_to_csp.html
Normal file
21
dom/security/test/csp/file_pdfjs_not_subject_to_csp.html
Normal file
@ -0,0 +1,21 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-allowPDF'">
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="pdfFrame"></iframe>
|
||||
<br/>
|
||||
<button id="pdfButton">click to load pdf</button>
|
||||
<script nonce="allowPDF">
|
||||
async function loadPDFIntoIframe() {
|
||||
let response = await fetch("dummy.pdf");
|
||||
let blob = await response.blob();
|
||||
var blobUrl = URL.createObjectURL(blob);
|
||||
var pdfFrame = document.getElementById("pdfFrame");
|
||||
pdfFrame.src = blobUrl;
|
||||
}
|
||||
let pdfButton = document.getElementById("pdfButton");
|
||||
pdfButton.addEventListener("click", loadPDFIntoIframe);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user