Bug 1864168 - Part 1: Use 1-origin column number in nsIContentSecurityPolicy. r=smaug,devtools-reviewers,ochameau,ckerschb

Differential Revision: https://phabricator.services.mozilla.com/D193369
This commit is contained in:
Tooru Fujisawa 2023-11-22 11:13:54 +00:00
parent e829ebfad1
commit a4a513ad86
27 changed files with 52 additions and 39 deletions

View File

@ -555,7 +555,7 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
csp->LogViolationDetails(violationType,
nullptr, // triggering element
cspEventListener, fileName, scriptSample, lineNum,
columnNum.zeroOriginValue(), u""_ns, u""_ns);
columnNum.oneOriginValue(), u""_ns, u""_ns);
}
return evalOK;

View File

@ -39,7 +39,7 @@ add_task(async function () {
`Content-Security-Policy: The pages 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";
const VIOLATION_LOCATION_JS = "test-csp-violation-inline.html:14:25";
await navigateTo(TEST_VIOLATION);
// Triggering the Violation via HTML
let msg = await waitFor(() => findErrorMessage(hud, CSP_VIOLATION));
@ -70,7 +70,7 @@ add_task(async function () {
"https://example.com/browser/devtools/client/webconsole/" +
"test/browser/test-csp-violation-base-uri.html";
const CSP_VIOLATION = `Content-Security-Policy: The pages settings blocked the loading of a resource at https://evil.com/ (“base-uri”).`;
const VIOLATION_LOCATION = "test-csp-violation-base-uri.html:15:24";
const VIOLATION_LOCATION = "test-csp-violation-base-uri.html:15:25";
await navigateTo(TEST_VIOLATION);
let msg = await waitFor(() => findErrorMessage(hud, CSP_VIOLATION));
ok(msg, "Base-URI validation was Printed");
@ -95,7 +95,7 @@ add_task(async function () {
"https://example.com/browser/devtools/client/webconsole/" +
"test/browser/test-csp-violation-form-action.html";
const CSP_VIOLATION = `Content-Security-Policy: The pages 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 VIOLATION_LOCATION = "test-csp-violation-form-action.html:14:40";
await navigateTo(TEST_VIOLATION);
const msg = await waitFor(() => findErrorMessage(hud, CSP_VIOLATION));

View File

@ -181,7 +181,7 @@ void nsStyledElement::ParseStyleAttribute(const nsAString& aValue,
if (!isNativeAnon &&
!nsStyleUtil::CSPAllowsInlineStyle(this, doc, aMaybeScriptedPrincipal, 0,
0, aValue, nullptr))
1, aValue, nullptr))
return;
if (aForceInDataDoc || !doc->IsLoadedAsData() || GetExistingStyle() ||

View File

@ -1046,7 +1046,7 @@ nsresult EventListenerManager::SetEventHandler(nsAtom* aName,
true, // aParserCreated (true because attribute event handler)
aElement,
nullptr, // nsICSPEventListener
aBody, lineNum, columnNum.zeroOriginValue(), &allowsInlineScript);
aBody, lineNum, columnNum.oneOriginValue(), &allowsInlineScript);
NS_ENSURE_SUCCESS(rv, rv);
// return early if CSP wants us to block inline scripts

View File

@ -1694,7 +1694,7 @@ nsresult HTMLFormElement::GetActionURL(nsIURI** aActionURL,
u""_ns, // aSourceFile
u""_ns, // aScriptSample
0, // aLineNumber
0, // aColumnNumber
1, // aColumnNumber
nsIScriptError::warningFlag, "upgradeInsecureRequest"_ns,
document->InnerWindowID(),
!!document->NodePrincipal()->OriginAttributesRef().mPrivateBrowsingId);

View File

@ -161,7 +161,7 @@ static bool AllowedByCSP(nsIContentSecurityPolicy* aCSP,
nullptr, // nsICSPEventListener
NS_ConvertASCIItoUTF16(aJavaScriptURL), // aContent
0, // aLineNumber
0, // aColumnNumber
1, // aColumnNumber
&allowsInlineScript);
return (NS_SUCCEEDED(rv) && allowsInlineScript);

View File

@ -919,7 +919,7 @@ static bool CSPAllowsInlineScript(nsIScriptElement* aElement,
nsIContentSecurityPolicy::SCRIPT_SRC_ELEM_DIRECTIVE,
false /* aHasUnsafeHash */, aNonce, parserCreated, element,
nullptr /* nsICSPEventListener */, u""_ns,
aElement->GetScriptLineNumber(), aElement->GetScriptColumnNumber(),
aElement->GetScriptLineNumber(), aElement->GetScriptColumnNumber() + 1,
&allowInlineScript);
return NS_SUCCEEDED(rv) && allowInlineScript;
}

View File

@ -137,6 +137,8 @@ nsresult CSPEvalChecker::CheckForWindow(JSContext* aCx,
&columnNum)) {
fileNameString.AssignLiteral("unknown");
}
// TODO: Use 1-origin in nsJSUtils::GetCallingLocation.
columnNum += 1;
nsCOMPtr<nsIContentSecurityPolicy> csp = doc->GetCsp();
rv = CheckInternal(csp, nullptr /* no CSPEventListener for window */,
@ -170,6 +172,8 @@ nsresult CSPEvalChecker::CheckForWorker(JSContext* aCx,
&columnNum)) {
fileNameString.AssignLiteral("unknown");
}
// TODO: Use 1-origin in nsJSUtils::GetCallingLocation.
columnNum += 1;
RefPtr<WorkerCSPCheckRunnable> r = new WorkerCSPCheckRunnable(
aWorkerPrivate, aExpression, fileNameString, lineNum, columnNum);

View File

@ -218,6 +218,8 @@ bool nsCSPContext::permitsInternal(
// If GetCallingLocation fails linenumber & columnNumber are set to 0
// anyway so we can skip checking if that is the case.
}
// TODO: Use 1-origin in nsJSUtils::GetCallingLocation.
columnNumber += 1;
AsyncReportViolation(
aTriggeringElement, aCSPEventListener,
(aSendContentLocationInViolationReports ? aContentLocation
@ -559,6 +561,9 @@ void nsCSPContext::reportInlineViolation(
}
lineNumber = aLineNumber;
columnNumber = aColumnNumber;
} else {
// TODO: Use 1-origin in nsJSUtils::GetCallingLocation.
columnNumber += 1;
}
AsyncReportViolation(aTriggeringElement, aCSPEventListener,
@ -740,6 +745,8 @@ nsCSPContext::GetAllowsNavigateTo(nsIURI* aURI, bool aIsFormSubmission,
// If GetCallingLocation fails linenumber & columnNumber are set to 0
// anyway so we can skip checking if that is the case.
}
// TODO: Use 1-origin in nsJSUtils::GetCallingLocation.
columnNumber += 1;
// Report the violation
nsresult rv = AsyncReportViolation(
@ -1848,7 +1855,7 @@ nsCSPContext::GetCSPSandboxFlags(uint32_t* aOutSandboxFlags) {
NS_ConvertUTF16toUTF8(policy).get()));
AutoTArray<nsString, 1> params = {policy};
logToConsole("ignoringReportOnlyDirective", params, u""_ns, u""_ns, 0, 0,
logToConsole("ignoringReportOnlyDirective", params, u""_ns, u""_ns, 0, 1,
nsIScriptError::warningFlag);
}
}

View File

@ -174,7 +174,7 @@ void nsCSPParser::logWarningErrorToConsole(uint32_t aSeverityFlag,
u""_ns, // aSourceName
u""_ns, // aSourceLine
0, // aLineNumber
0, // aColumnNumber
1, // aColumnNumber
aSeverityFlag); // aFlags
}

View File

@ -692,6 +692,8 @@ bool nsContentSecurityUtils::IsEvalAllowed(JSContext* cx,
if (fileName.IsEmpty()) {
fileName = "unknown-file"_ns;
}
// TODO: Use 1-origin in nsJSUtils::GetCallingLocation.
columnNumber += 1;
NS_ConvertUTF8toUTF16 fileNameA(fileName);
for (const nsLiteralCString& allowlistEntry : evalAllowlist) {
@ -1152,7 +1154,7 @@ void EnforceXFrameOptionsCheck(nsIChannel* aChannel,
u""_ns, // no sourcefile
u""_ns, // no scriptsample
0, // no linenumber
0, // no columnnumber
1, // no columnnumber
nsIScriptError::warningFlag,
"IgnoringSrcBecauseOfDirective"_ns, innerWindowID,
privateWindow);

View File

@ -810,7 +810,7 @@ nsresult nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
u""_ns, // aSourceFile
u""_ns, // aScriptSample
0, // aLineNumber
0, // aColumnNumber
1, // aColumnNumber
nsIScriptError::errorFlag, "blockAllMixedContent"_ns,
requestingWindow->Id(),
!!aLoadInfo->GetOriginAttributes().mPrivateBrowsingId);

View File

@ -140,8 +140,8 @@ function run_test() {
null, // nsICSPEventListener
"", // aContentOfPseudoScript
0, // aLineNumber
0
); // aColumnNumber
1 // aColumnNumber
);
// this is not a report only policy, so it better block inline scripts
Assert.ok(!inlineOK);
@ -181,8 +181,8 @@ function run_test() {
// note that JSON is UTF8 encoded.
"\u00a3\u00a5\u00b5\u5317\ud841\udf79",
1, // line number
2
); // column number
2 // column number
);
}
}
);
@ -220,8 +220,8 @@ function run_test() {
null, // nsICSPEventListener
"", // aContentOfPseudoScript
0, // aLineNumber
0
); // aColumnNumber
1 // aColumnNumber
);
// this is a report only policy, so it better allow inline scripts
Assert.ok(inlineOK);
@ -248,8 +248,8 @@ function run_test() {
selfuri.asciiSpec,
"script sample",
4, // line number
5
); // column number
5 // column number
);
}
});

View File

@ -453,7 +453,7 @@ void SMILCSSValueType::ValueFromString(nsCSSPropertyID aPropID,
}
Document* doc = aTargetElement->GetComposedDoc();
if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr, doc, nullptr, 0, 0,
if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr, doc, nullptr, 0, 1,
aString, nullptr)) {
return;
}
@ -490,7 +490,7 @@ SMILValue SMILCSSValueType::ValueFromAnimationValue(
// and an intermediate CSS value is not likely to be particularly useful
// in that case, we just use a generic placeholder string instead.
static const nsLiteralString kPlaceholderText = u"[SVG animation of CSS]"_ns;
if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr, doc, nullptr, 0, 0,
if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr, doc, nullptr, 0, 1,
kPlaceholderText, nullptr)) {
return result;
}

View File

@ -1728,7 +1728,7 @@ nsresult WebSocketImpl::Init(JSContext* aCx, bool aIsSecure,
u""_ns, // aSourceFile
u""_ns, // aScriptSample
0, // aLineNumber
0, // aColumnNumber
1, // aColumnNumber
nsIScriptError::warningFlag,
"upgradeInsecureRequest"_ns, mInnerWindowID,
mPrivateBrowsing);

View File

@ -531,7 +531,7 @@ bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind,
RefPtr<LogViolationDetailsRunnable> runnable =
new LogViolationDetailsRunnable(worker, violationType, fileName,
lineNum, columnNum.zeroOriginValue(),
lineNum, columnNum.oneOriginValue(),
scriptSample);
ErrorResult rv;

View File

@ -519,7 +519,7 @@ nsresult nsXMLContentSink::CreateElement(
}
if (!aNodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
linkStyle->SetLineNumber(aFromParser ? aLineNumber : 0);
linkStyle->SetColumnNumber(aFromParser ? aColumnNumber : 0);
linkStyle->SetColumnNumber(aFromParser ? aColumnNumber + 1 : 1);
}
}

View File

@ -2921,7 +2921,7 @@ static bool ShouldSecureUpgradeNoHSTS(nsIURI* aURI, nsILoadInfo* aLoadInfo) {
u""_ns, // aSourceFile
u""_ns, // aScriptSample
0, // aLineNumber
0, // aColumnNumber
1, // aColumnNumber
nsIScriptError::warningFlag,
"upgradeInsecureRequest"_ns, innerWindowId,
!!aLoadInfo->GetOriginAttributes().mPrivateBrowsingId);

View File

@ -8,7 +8,7 @@
watcher.wait_for('securitypolicyviolation').then(t.step_func_done(e => {
assert_equals(e.blockedURI, "eval");
assert_equals(e.lineNumber, 15);
assert_equals(e.columnNumber, 12);
assert_equals(e.columnNumber, 13);
}));
try {

View File

@ -8,7 +8,7 @@
watcher.wait_for('securitypolicyviolation').then(t.step_func_done(e => {
assert_equals(e.blockedURI, "inline");
assert_equals(e.lineNumber, 15);
assert_equals(e.columnNumber, 8);
assert_equals(e.columnNumber, 9);
}));
}, "Inline violations have a blockedURI of 'inline'");
</script>

View File

@ -17,7 +17,7 @@
assert_equals(e.disposition, "enforce");
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.columnNumber, 1);
assert_equals(e.statusCode, 200);
}));

View File

@ -17,7 +17,7 @@
assert_equals(e.disposition, "enforce");
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.columnNumber, 5);
assert_equals(e.statusCode, 200);
}));

View File

@ -17,7 +17,7 @@
assert_equals(e.disposition, "enforce");
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.columnNumber, 1);
assert_equals(e.statusCode, 200);
}));

View File

@ -17,7 +17,7 @@
assert_equals(e.disposition, "enforce");
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.columnNumber, 5);
assert_equals(e.statusCode, 200);
}));

View File

@ -9,7 +9,7 @@
assert_equals(e.blockedURI, "eval");
assert_equals(e.sourceFile, "blob");
assert_equals(e.lineNumber, 3);
assert_equals(e.columnNumber, 16);
assert_equals(e.columnNumber, 17);
}));
var scriptText = `

View File

@ -9,7 +9,7 @@
assert_equals(e.blockedURI, "eval");
assert_equals(e.sourceFile, "data");
assert_equals(e.lineNumber, 3);
assert_equals(e.columnNumber, 16);
assert_equals(e.columnNumber, 17);
}));
var scriptText = `

View File

@ -36,28 +36,28 @@
.then(t.step_func(e => {
assert_equals(e.blockedURI, "inline");
assert_equals(e.lineNumber, 118);
assert_in_array(e.columnNumber, [4, 6]);
assert_in_array(e.columnNumber, [5, 7]);
assert_equals(e.target, document, "Elements created in this document, but pushed into a same-origin frame trigger on that frame's document, not on this frame's document.");
return watcher.wait_for('securitypolicyviolation');
}))
.then(t.step_func(e => {
assert_equals(e.blockedURI, "inline");
assert_equals(e.lineNumber, 131);
assert_in_array(e.columnNumber, [4, 59]);
assert_in_array(e.columnNumber, [5, 60]);
assert_equals(e.target, document, "Elements created in this document, but pushed into a same-origin frame trigger on that frame's document, not on this frame's document.");
return watcher.wait_for('securitypolicyviolation');
}))
.then(t.step_func(e => {
assert_equals(e.blockedURI, "inline");
assert_equals(e.lineNumber, 139);
assert_in_array(e.columnNumber, [4, 6]);
assert_in_array(e.columnNumber, [5, 7]);
assert_equals(e.target, document, "Inline event handlers for disconnected elements target the document.");
return watcher.wait_for('securitypolicyviolation');
}))
.then(t.step_func(e => {
assert_equals(e.blockedURI, "inline");
assert_equals(e.lineNumber, 0);
assert_equals(e.columnNumber, 0);
assert_equals(e.columnNumber, 1);
assert_equals(e.target, document, "Inline event handlers for elements disconnected after triggering target the document.");
}))
.then(t.step_func_done(_ => {