зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1100630 - Print Related JS-Line on CSP Violation (if any) r=ckerschb,dveditz
Differential Revision: https://phabricator.services.mozilla.com/D31420 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
0c19ebd386
Коммит
d19c155e9e
|
@ -23,6 +23,16 @@ support-files =
|
|||
test-cd-iframe-parent.html
|
||||
test-console-api-iframe.html
|
||||
test-csp-violation.html
|
||||
test-csp-violation-inline.html
|
||||
test-csp-violation-inline.html^headers^
|
||||
test-csp-violation-base-uri.html
|
||||
test-csp-violation-base-uri.html^headers^
|
||||
test-csp-violation-form-action.html
|
||||
test-csp-violation-form-action.html^headers^
|
||||
test-csp-violation-frame-ancestor-child.html^headers^
|
||||
test-csp-violation-frame-ancestor-child.html
|
||||
test-csp-violation-frame-ancestor-parent.html^headers^
|
||||
test-csp-violation-frame-ancestor-parent.html
|
||||
test-cspro.html
|
||||
test-cspro.html^headers^
|
||||
test-iframe-child.html
|
||||
|
|
|
@ -8,22 +8,105 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,Web Console CSP violation test";
|
||||
const TEST_VIOLATION =
|
||||
"https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/mochitest/test-csp-violation.html";
|
||||
const CSP_VIOLATION_MSG =
|
||||
"Content Security Policy: The page\u2019s settings " +
|
||||
"blocked the loading of a resource at " +
|
||||
"http://some.example.com/test.png (\u201cimg-src\u201d).";
|
||||
|
||||
add_task(async function() {
|
||||
const TEST_URI = "data:text/html;charset=utf8,Web Console CSP violation test";
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
hud.ui.clearOutput();
|
||||
{
|
||||
const TEST_VIOLATION =
|
||||
"https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/mochitest/test-csp-violation.html";
|
||||
const CSP_VIOLATION_MSG =
|
||||
"Content Security Policy: The page\u2019s settings " +
|
||||
"blocked the loading of a resource at " +
|
||||
"http://some.example.com/test.png (\u201cimg-src\u201d).";
|
||||
const onRepeatedMessage = waitForRepeatedMessage(hud, CSP_VIOLATION_MSG, 2);
|
||||
await loadDocument(TEST_VIOLATION);
|
||||
await onRepeatedMessage;
|
||||
ok(true, "Received expected messages");
|
||||
}
|
||||
hud.ui.clearOutput();
|
||||
// Testing CSP Inline Violations
|
||||
{
|
||||
const TEST_VIOLATION =
|
||||
"https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/mochitest/test-csp-violation-inline.html";
|
||||
const CSP_VIOLATION =
|
||||
`Content Security Policy: The page’s settings blocked` +
|
||||
` the loading of a resource at inline (“style-src”).`;
|
||||
const VIOLATION_LOCATION_HTML = "test-csp-violation-inline.html:18:1";
|
||||
const VIOLATION_LOCATION_JS = "test-csp-violation-inline.html:14:24";
|
||||
await loadDocument(TEST_VIOLATION);
|
||||
// Triggering the Violation via HTML
|
||||
let msg = await waitFor(() => findMessage(hud, CSP_VIOLATION));
|
||||
let locationNode = msg.querySelector(".message-location");
|
||||
info(`EXPECT ${VIOLATION_LOCATION_HTML} GOT: ${locationNode.textContent}`);
|
||||
ok(
|
||||
locationNode.textContent == VIOLATION_LOCATION_HTML,
|
||||
"Printed the CSP Violation with HTML Context"
|
||||
);
|
||||
// Triggering the Violation via JS
|
||||
hud.ui.clearOutput();
|
||||
hud.jsterm.execute("window.violate()");
|
||||
msg = await waitFor(() => findMessage(hud, CSP_VIOLATION));
|
||||
locationNode = msg.querySelector(".message-location");
|
||||
info(`EXPECT ${VIOLATION_LOCATION_JS} GOT: ${locationNode.textContent}`);
|
||||
ok(
|
||||
locationNode.textContent == VIOLATION_LOCATION_JS,
|
||||
"Printed the CSP Violation with JS Context"
|
||||
);
|
||||
}
|
||||
hud.ui.clearOutput();
|
||||
// Testing Base URI
|
||||
{
|
||||
const TEST_VIOLATION =
|
||||
"https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/mochitest/test-csp-violation-base-uri.html";
|
||||
const CSP_VIOLATION = `Content Security Policy: The page’s settings blocked the loading of a resource at https://evil.com/ (“base-uri”).`;
|
||||
const VIOLATION_LOCATION = "test-csp-violation-base-uri.html:15:24";
|
||||
await loadDocument(TEST_VIOLATION);
|
||||
let msg = await waitFor(() => findMessage(hud, CSP_VIOLATION));
|
||||
ok(msg, "Base-URI validation was Printed");
|
||||
// Triggering the Violation via JS
|
||||
hud.ui.clearOutput();
|
||||
hud.jsterm.execute("window.violate()");
|
||||
msg = await waitFor(() => findMessage(hud, CSP_VIOLATION));
|
||||
const locationNode = msg.querySelector(".message-location");
|
||||
console.log(locationNode.textContent);
|
||||
ok(
|
||||
locationNode.textContent == VIOLATION_LOCATION,
|
||||
"Base-URI validation was Printed with the Responsible JS Line"
|
||||
);
|
||||
}
|
||||
hud.ui.clearOutput();
|
||||
// Testing CSP Form Action
|
||||
{
|
||||
const TEST_VIOLATION =
|
||||
"https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/mochitest/test-csp-violation-form-action.html";
|
||||
const CSP_VIOLATION = `Content Security Policy: The page’s settings blocked the loading of a resource at https://evil.com/evil.com (“form-action”).`;
|
||||
const VIOLATION_LOCATION = "test-csp-violation-form-action.html:14:39";
|
||||
|
||||
const onRepeatedMessage = waitForRepeatedMessage(hud, CSP_VIOLATION_MSG, 2);
|
||||
await loadDocument(TEST_VIOLATION);
|
||||
await onRepeatedMessage;
|
||||
|
||||
ok(true, "Received expected messages");
|
||||
await loadDocument(TEST_VIOLATION);
|
||||
const msg = await waitFor(() => findMessage(hud, CSP_VIOLATION));
|
||||
const locationNode = msg.querySelector(".message-location");
|
||||
info(`EXPECT ${VIOLATION_LOCATION} GOT: ${locationNode.textContent}`);
|
||||
ok(
|
||||
locationNode.textContent == VIOLATION_LOCATION,
|
||||
"JS Line which Triggered the CSP-Form Action Violation was Printed"
|
||||
);
|
||||
}
|
||||
hud.ui.clearOutput();
|
||||
// Testing CSP Frame Ancestors Directive
|
||||
{
|
||||
const TEST_VIOLATION =
|
||||
"https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/mochitest/test-csp-violation-frame-ancestor-parent.html";
|
||||
const CSP_VIOLATION =
|
||||
`Content Security Policy: The page’s settings blocked` +
|
||||
` the loading of a resource at ${TEST_VIOLATION} (“frame-ancestors”).`;
|
||||
await loadDocument(TEST_VIOLATION);
|
||||
const msg = await waitFor(() => findMessage(hud, CSP_VIOLATION));
|
||||
ok(msg, "Frame-Ancestors violation by html was printed");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>CSP Base-URI Violation Test </title>
|
||||
<base href="https://evil.com/">
|
||||
</head>
|
||||
<body>
|
||||
<h1> Crashing the Base Element</h1>
|
||||
</body>
|
||||
<script>
|
||||
"use strict";
|
||||
window.violate = ()=>{
|
||||
document.head.innerHTML = "";
|
||||
const b = document.createElement("base");
|
||||
b.href = "https://evil.com";
|
||||
document.head.append(b);
|
||||
};
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: base-uri 'self';
|
|
@ -0,0 +1,16 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>CSP Base-URI Violation Test </title>
|
||||
<base href="https://evil.com/">
|
||||
</head>
|
||||
<body>
|
||||
<form action="evil.com" >
|
||||
<input type="text" value="test" name="test" />
|
||||
<button type="submit">Submit Button</button>
|
||||
</form>
|
||||
</body>
|
||||
<script>
|
||||
"use strict";
|
||||
document.querySelector("form").submit();
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: form-action 'self';
|
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>CSP frame-ancestors Violation Test </title>
|
||||
<base href="https://evil.com/">
|
||||
</head>
|
||||
<body>
|
||||
<h1> This Should not be Loadable</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: frame-ancestors 'none';
|
|
@ -0,0 +1,21 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>CSP frame-ancestors Violation Test </title>
|
||||
<base href="https://evil.com/">
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="https://example.com/browser/devtools/client/webconsole/test/mochitest/test-csp-violation-frame-ancestor-child.html">
|
||||
</iframe>
|
||||
</body>
|
||||
<script>
|
||||
"use strict";
|
||||
window.violate = ()=>{
|
||||
const iframe = document.querySelector("iframe");
|
||||
const src = iframe.src;
|
||||
iframe.src = "";
|
||||
requestAnimationFrame(() => {
|
||||
iframe.src = src;
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: form-action 'self';
|
|
@ -0,0 +1,21 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>CSP Inline Violations Test</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
This Background should be neither Red nor Blue c:
|
||||
</body>
|
||||
<script>
|
||||
"use strict";
|
||||
window.violate = () =>{
|
||||
const style = document.createElement("style");
|
||||
style.innerHTML = "body { background-color: red; }";
|
||||
document.head.appendChild(style);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
background-color:blue;
|
||||
</style>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: style-src 'self';
|
|
@ -53,6 +53,7 @@
|
|||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsJSUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -211,6 +212,15 @@ bool nsCSPContext::permitsInternal(
|
|||
// decision may be wrong due to the inability to get the nonce, and will
|
||||
// incorrectly fail the unit tests.
|
||||
if (!aIsPreload && aSendViolationReports) {
|
||||
uint32_t lineNumber = 0;
|
||||
uint32_t columnNumber = 0;
|
||||
nsAutoCString spec;
|
||||
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (cx) {
|
||||
nsJSUtils::GetCallingLocation(cx, spec, &lineNumber, &columnNumber);
|
||||
// If GetCallingLocation fails linenumber & columnNumber are set to 0
|
||||
// anyway so we can skip checking if that is the case.
|
||||
}
|
||||
AsyncReportViolation(
|
||||
aTriggeringElement, aCSPEventListener,
|
||||
(aSendContentLocationInViolationReports ? aContentLocation
|
||||
|
@ -220,10 +230,10 @@ bool nsCSPContext::permitsInternal(
|
|||
null */
|
||||
violatedDirective, p, /* policy index */
|
||||
EmptyString(), /* no observer subject */
|
||||
EmptyString(), /* no source file */
|
||||
EmptyString(), /* no script sample */
|
||||
0, /* no line number */
|
||||
0); /* no column number */
|
||||
NS_ConvertUTF8toUTF16(spec), /* source file */
|
||||
EmptyString(), /* no script sample */
|
||||
lineNumber, /* line number */
|
||||
columnNumber); /* column number */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -487,6 +497,21 @@ void nsCSPContext::reportInlineViolation(
|
|||
mSelfURI->GetSpec(sourceFile);
|
||||
}
|
||||
|
||||
uint32_t lineNumber = aLineNumber;
|
||||
uint32_t columnNumber = aColumnNumber;
|
||||
|
||||
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (cx) {
|
||||
if (!nsJSUtils::GetCallingLocation(cx, sourceFile, &lineNumber,
|
||||
&columnNumber)) {
|
||||
// Get Calling Location resets line/col to 0
|
||||
// so we reset those to the intial arguments
|
||||
// in case it failed
|
||||
lineNumber = aLineNumber;
|
||||
columnNumber = aColumnNumber;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncReportViolation(aTriggeringElement, aCSPEventListener,
|
||||
nullptr, // aBlockedURI
|
||||
BlockedContentSource::eInline, // aBlockedSource
|
||||
|
@ -496,8 +521,8 @@ void nsCSPContext::reportInlineViolation(
|
|||
observerSubject, // aObserverSubject
|
||||
NS_ConvertUTF8toUTF16(sourceFile), // aSourceFile
|
||||
aContent, // aScriptSample
|
||||
aLineNumber, // aLineNum
|
||||
aColumnNumber); // aColumnNum
|
||||
lineNumber, // aLineNum
|
||||
columnNumber); // aColumnNum
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
assert_equals(e.effectiveDirective, "img-src");
|
||||
assert_equals(e.originalPolicy, "img-src \'none\'");
|
||||
assert_equals(e.disposition, "enforce");
|
||||
assert_equals(e.sourceFile, "");
|
||||
assert_equals(e.lineNumber, 0);
|
||||
assert_equals(new URL(e.sourceFile).pathname, "/content-security-policy/support/inject-image.sub.js");
|
||||
assert_equals(e.lineNumber, 2);
|
||||
assert_equals(e.columnNumber, 0);
|
||||
assert_equals(e.statusCode, 200);
|
||||
}));
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
assert_equals(e.effectiveDirective, "img-src");
|
||||
assert_equals(e.originalPolicy, "img-src \'none\'");
|
||||
assert_equals(e.disposition, "enforce");
|
||||
assert_equals(e.sourceFile, "");
|
||||
assert_equals(e.lineNumber, 0);
|
||||
assert_equals(e.columnNumber, 0);
|
||||
assert_equals(new URL(e.sourceFile).pathname, "/content-security-policy/securitypolicyviolation/securitypolicyviolation-block-cross-origin-image.sub.html");
|
||||
assert_equals(e.lineNumber, 25);
|
||||
assert_equals(e.columnNumber, 4);
|
||||
assert_equals(e.statusCode, 200);
|
||||
}));
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
assert_equals(e.effectiveDirective, "img-src");
|
||||
assert_equals(e.originalPolicy, "img-src \'none\'");
|
||||
assert_equals(e.disposition, "enforce");
|
||||
assert_equals(e.sourceFile, "");
|
||||
assert_equals(e.lineNumber, 0);
|
||||
assert_equals(new URL(e.sourceFile).pathname, "/content-security-policy/support/inject-image.sub.js");
|
||||
assert_equals(e.lineNumber, 2);
|
||||
assert_equals(e.columnNumber, 0);
|
||||
assert_equals(e.statusCode, 200);
|
||||
}));
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
assert_equals(e.effectiveDirective, "img-src");
|
||||
assert_equals(e.originalPolicy, "img-src \'none\'");
|
||||
assert_equals(e.disposition, "enforce");
|
||||
assert_equals(e.sourceFile, "");
|
||||
assert_equals(e.lineNumber, 0);
|
||||
assert_equals(e.columnNumber, 0);
|
||||
assert_equals(new URL(e.sourceFile).pathname, "/content-security-policy/securitypolicyviolation/securitypolicyviolation-block-image.sub.html");
|
||||
assert_equals(e.lineNumber, 25);
|
||||
assert_equals(e.columnNumber, 4);
|
||||
assert_equals(e.statusCode, 200);
|
||||
}));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче