From fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:14:29 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- dom/security/nsCSPContext.cpp | 225 ++++++++++++++++++++++++++++-------------- 1 file changed, 152 insertions(+), 73 deletions(-) (limited to 'dom/security/nsCSPContext.cpp') diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index aafd2b64f2..ed44304484 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -189,10 +189,11 @@ bool nsCSPContext::permitsInternal( bool permits = true; nsAutoString violatedDirective; + nsAutoString violatedDirectiveString; for (uint32_t p = 0; p < mPolicies.Length(); p++) { if (!mPolicies[p]->permits(aDir, aLoadInfo, aContentLocation, !!aOriginalURIIfRedirect, aSpecific, - violatedDirective)) { + violatedDirective, violatedDirectiveString)) { // If the policy is violated and not report-only, reject the load and // report to the console if (!mPolicies[p]->getReportOnlyFlag()) { @@ -200,12 +201,6 @@ bool nsCSPContext::permitsInternal( permits = false; } - // In CSP 3.0 the effective directive doesn't become the actually used - // directive in case of a fallback from e.g. script-src-elem to - // script-src or default-src. - nsAutoString effectiveDirective; - effectiveDirective.AssignASCII(CSP_CSPDirectiveToString(aDir)); - // Callers should set |aSendViolationReports| to false if this is a // preload - the decision may be wrong due to the inability to get the // nonce, and will incorrectly fail the unit tests. @@ -226,9 +221,11 @@ bool nsCSPContext::permitsInternal( BlockedContentSource::eUnknown, /* a BlockedContentSource */ aOriginalURIIfRedirect, /* in case of redirect originalURI is not null */ - violatedDirective, effectiveDirective, p, /* policy index */ - u""_ns, /* no observer subject */ - spec, /* source file */ + violatedDirective, violatedDirectiveString, + aDir, // aViolatedDirective + p, // policy index + u""_ns, // no observer subject + spec, // source file false, // aReportSample (no sample) u""_ns, /* no script sample */ lineNumber, /* line number */ @@ -519,7 +516,8 @@ void nsCSPContext::reportInlineViolation( CSPDirective aDirective, Element* aTriggeringElement, nsICSPEventListener* aCSPEventListener, const nsAString& aNonce, bool aReportSample, const nsAString& aSample, - const nsAString& aViolatedDirective, const nsAString& aEffectiveDirective, + const nsAString& aViolatedDirective, + const nsAString& aViolatedDirectiveString, CSPDirective aEffectiveDirective, uint32_t aViolatedPolicyIndex, // TODO, use report only flag for that uint32_t aLineNumber, uint32_t aColumnNumber) { nsString observerSubject; @@ -564,14 +562,15 @@ void nsCSPContext::reportInlineViolation( BlockedContentSource::eInline, // aBlockedSource mSelfURI, // aOriginalURI aViolatedDirective, // aViolatedDirective - aEffectiveDirective, // aEffectiveDirective - aViolatedPolicyIndex, // aViolatedPolicyIndex - observerSubject, // aObserverSubject - sourceFile, // aSourceFile - aReportSample, // aReportSample - aSample, // aScriptSample - lineNumber, // aLineNum - columnNumber); // aColumnNum + aViolatedDirectiveString, + aEffectiveDirective, // aEffectiveDirective + aViolatedPolicyIndex, // aViolatedPolicyIndex + observerSubject, // aObserverSubject + sourceFile, // aSourceFile + aReportSample, // aReportSample + aSample, // aScriptSample + lineNumber, // aLineNum + columnNumber); // aColumnNum } NS_IMETHODIMP @@ -672,19 +671,16 @@ nsCSPContext::GetAllowsInline(CSPDirective aDirective, bool aHasUnsafeHash, *outAllowsInline = false; } nsAutoString violatedDirective; + nsAutoString violatedDirectiveString; bool reportSample = false; - mPolicies[i]->getDirectiveStringAndReportSampleForContentType( - aDirective, violatedDirective, &reportSample); - - // In CSP 3.0 the effective directive doesn't become the actually used - // directive in case of a fallback from e.g. script-src-elem to - // script-src or default-src. - nsAutoString effectiveDirective; - effectiveDirective.AssignASCII(CSP_CSPDirectiveToString(aDirective)); + mPolicies[i]->getViolatedDirectiveInformation( + aDirective, violatedDirective, violatedDirectiveString, + &reportSample); reportInlineViolation(aDirective, aTriggeringElement, aCSPEventListener, aNonce, reportSample, content, violatedDirective, - effectiveDirective, i, aLineNumber, aColumnNumber); + violatedDirectiveString, aDirective, i, aLineNumber, + aColumnNumber); } } @@ -747,15 +743,18 @@ nsCSPContext::LogViolationDetails( } nsAutoString violatedDirective; + nsAutoString violatedDirectiveString; bool reportSample = false; - mPolicies[p]->getDirectiveStringAndReportSampleForContentType( - SCRIPT_SRC_DIRECTIVE, violatedDirective, &reportSample); + mPolicies[p]->getViolatedDirectiveInformation( + SCRIPT_SRC_DIRECTIVE, violatedDirective, violatedDirectiveString, + &reportSample); - AsyncReportViolation(aTriggeringElement, aCSPEventListener, nullptr, - blockedContentSource, nullptr, violatedDirective, - u"script-src"_ns /* aEffectiveDirective */, p, - observerSubject, aSourceFile, reportSample, - aScriptSample, aLineNum, aColumnNum); + AsyncReportViolation( + aTriggeringElement, aCSPEventListener, nullptr, blockedContentSource, + nullptr, violatedDirective, violatedDirectiveString, + CSPDirective::SCRIPT_SRC_DIRECTIVE /* aEffectiveDirective */, p, + observerSubject, aSourceFile, reportSample, aScriptSample, aLineNum, + aColumnNum); } return NS_OK; } @@ -1375,10 +1374,12 @@ class CSPReportSenderRunnable final : public Runnable { nsIURI* aBlockedURI, nsCSPContext::BlockedContentSource aBlockedContentSource, nsIURI* aOriginalURI, uint32_t aViolatedPolicyIndex, bool aReportOnlyFlag, - const nsAString& aViolatedDirective, const nsAString& aEffectiveDirective, - const nsAString& aObserverSubject, const nsAString& aSourceFile, - bool aReportSample, const nsAString& aScriptSample, uint32_t aLineNum, - uint32_t aColumnNum, nsCSPContext* aCSPContext) + const nsAString& aViolatedDirective, + const nsAString& aViolatedDirectiveString, + const CSPDirective aEffectiveDirective, const nsAString& aObserverSubject, + const nsAString& aSourceFile, bool aReportSample, + const nsAString& aScriptSample, uint32_t aLineNum, uint32_t aColumnNum, + nsCSPContext* aCSPContext) : mozilla::Runnable("CSPReportSenderRunnable"), mTriggeringElement(aTriggeringElement), mCSPEventListener(aCSPEventListener), @@ -1389,6 +1390,7 @@ class CSPReportSenderRunnable final : public Runnable { mReportOnlyFlag(aReportOnlyFlag), mReportSample(aReportSample), mViolatedDirective(aViolatedDirective), + mViolatedDirectiveString(aViolatedDirectiveString), mEffectiveDirective(aEffectiveDirective), mSourceFile(aSourceFile), mScriptSample(aScriptSample), @@ -1436,16 +1438,18 @@ class CSPReportSenderRunnable final : public Runnable { NS_IMETHOD Run() override { MOZ_ASSERT(NS_IsMainThread()); - nsresult rv; - // 0) prepare violation data mozilla::dom::SecurityPolicyViolationEventInit init; nsAutoCString blockedContentSource; BlockedContentSourceToString(mBlockedContentSource, blockedContentSource); - rv = mCSPContext->GatherSecurityPolicyViolationEventData( - mBlockedURI, blockedContentSource, mOriginalURI, mEffectiveDirective, + nsAutoString effectiveDirective; + effectiveDirective.AssignASCII( + CSP_CSPDirectiveToString(mEffectiveDirective)); + + nsresult rv = mCSPContext->GatherSecurityPolicyViolationEventData( + mBlockedURI, blockedContentSource, mOriginalURI, effectiveDirective, mViolatedPolicyIndex, mSourceFile, mReportSample ? mScriptSample : EmptyString(), mLineNum, mColumnNum, init); @@ -1464,32 +1468,7 @@ class CSPReportSenderRunnable final : public Runnable { mCSPContext->SendReports(init, mViolatedPolicyIndex); // 3) log to console (one per policy violation) - - if (mBlockedURI) { - mBlockedURI->GetSpec(blockedContentSource); - if (blockedContentSource.Length() > - nsCSPContext::ScriptSampleMaxLength()) { - bool isData = mBlockedURI->SchemeIs("data"); - if (NS_SUCCEEDED(rv) && isData && - blockedContentSource.Length() > - nsCSPContext::ScriptSampleMaxLength()) { - blockedContentSource.Truncate(nsCSPContext::ScriptSampleMaxLength()); - blockedContentSource.Append( - NS_ConvertUTF16toUTF8(nsContentUtils::GetLocalizedEllipsis())); - } - } - } - - if (blockedContentSource.Length() > 0) { - nsString blockedContentSource16 = - NS_ConvertUTF8toUTF16(blockedContentSource); - AutoTArray params = {mViolatedDirective, - blockedContentSource16}; - mCSPContext->logToConsole( - mReportOnlyFlag ? "CSPROViolationWithURI" : "CSPViolationWithURI", - params, mSourceFile, mScriptSample, mLineNum, mColumnNum, - nsIScriptError::errorFlag); - } + ReportToConsole(); // 4) fire violation event // A frame-ancestors violation has occurred, but we should not dispatch @@ -1503,6 +1482,104 @@ class CSPReportSenderRunnable final : public Runnable { } private: + void ReportToConsole() const { + NS_ConvertUTF8toUTF16 effectiveDirective( + CSP_CSPDirectiveToString(mEffectiveDirective)); + + switch (mBlockedContentSource) { + case nsCSPContext::BlockedContentSource::eInline: { + const char* errorName = nullptr; + if (mEffectiveDirective == CSPDirective::STYLE_SRC_ATTR_DIRECTIVE || + mEffectiveDirective == CSPDirective::STYLE_SRC_ELEM_DIRECTIVE) { + errorName = mReportOnlyFlag ? "CSPROInlineStyleViolation" + : "CSPInlineStyleViolation"; + } else if (mEffectiveDirective == + CSPDirective::SCRIPT_SRC_ATTR_DIRECTIVE) { + errorName = mReportOnlyFlag ? "CSPROEventHandlerScriptViolation" + : "CSPEventHandlerScriptViolation"; + } else { + MOZ_ASSERT(mEffectiveDirective == + CSPDirective::SCRIPT_SRC_ELEM_DIRECTIVE); + errorName = mReportOnlyFlag ? "CSPROInlineScriptViolation" + : "CSPInlineScriptViolation"; + } + + AutoTArray params = {mViolatedDirectiveString, + effectiveDirective}; + mCSPContext->logToConsole(errorName, params, mSourceFile, mScriptSample, + mLineNum, mColumnNum, + nsIScriptError::errorFlag); + break; + } + + case nsCSPContext::BlockedContentSource::eEval: { + AutoTArray params = {mViolatedDirectiveString, + effectiveDirective}; + mCSPContext->logToConsole(mReportOnlyFlag ? "CSPROEvalScriptViolation" + : "CSPEvalScriptViolation", + params, mSourceFile, mScriptSample, mLineNum, + mColumnNum, nsIScriptError::errorFlag); + break; + } + + case nsCSPContext::BlockedContentSource::eWasmEval: { + AutoTArray params = {mViolatedDirectiveString, + effectiveDirective}; + mCSPContext->logToConsole(mReportOnlyFlag + ? "CSPROWasmEvalScriptViolation" + : "CSPWasmEvalScriptViolation", + params, mSourceFile, mScriptSample, mLineNum, + mColumnNum, nsIScriptError::errorFlag); + break; + } + + case nsCSPContext::BlockedContentSource::eSelf: + case nsCSPContext::BlockedContentSource::eUnknown: { + nsAutoString source(u""_ns); + if (mBlockedURI) { + nsAutoCString uri; + mBlockedURI->GetSpec(uri); + + if (mBlockedURI->SchemeIs("data") && + uri.Length() > nsCSPContext::ScriptSampleMaxLength()) { + uri.Truncate(nsCSPContext::ScriptSampleMaxLength()); + uri.Append( + NS_ConvertUTF16toUTF8(nsContentUtils::GetLocalizedEllipsis())); + } + + if (!uri.IsEmpty()) { + CopyUTF8toUTF16(uri, source); + } + } + + const char* errorName = nullptr; + switch (mEffectiveDirective) { + case CSPDirective::STYLE_SRC_ELEM_DIRECTIVE: + errorName = + mReportOnlyFlag ? "CSPROStyleViolation" : "CSPStyleViolation"; + break; + case CSPDirective::SCRIPT_SRC_ELEM_DIRECTIVE: + errorName = + mReportOnlyFlag ? "CSPROScriptViolation" : "CSPScriptViolation"; + break; + case CSPDirective::WORKER_SRC_DIRECTIVE: + errorName = + mReportOnlyFlag ? "CSPROWorkerViolation" : "CSPWorkerViolation"; + break; + default: + errorName = mReportOnlyFlag ? "CSPROGenericViolation" + : "CSPGenericViolation"; + } + + AutoTArray params = {mViolatedDirectiveString, source, + effectiveDirective}; + mCSPContext->logToConsole(errorName, params, mSourceFile, mScriptSample, + mLineNum, mColumnNum, + nsIScriptError::errorFlag); + } + } + } + RefPtr mTriggeringElement; nsCOMPtr mCSPEventListener; nsCOMPtr mBlockedURI; @@ -1512,7 +1589,8 @@ class CSPReportSenderRunnable final : public Runnable { bool mReportOnlyFlag; bool mReportSample; nsString mViolatedDirective; - nsString mEffectiveDirective; + nsString mViolatedDirectiveString; + CSPDirective mEffectiveDirective; nsCOMPtr mObserverSubject; nsString mSourceFile; nsString mScriptSample; @@ -1554,7 +1632,8 @@ nsresult nsCSPContext::AsyncReportViolation( Element* aTriggeringElement, nsICSPEventListener* aCSPEventListener, nsIURI* aBlockedURI, BlockedContentSource aBlockedContentSource, nsIURI* aOriginalURI, const nsAString& aViolatedDirective, - const nsAString& aEffectiveDirective, uint32_t aViolatedPolicyIndex, + const nsAString& aViolatedDirectiveString, + const CSPDirective aEffectiveDirective, uint32_t aViolatedPolicyIndex, const nsAString& aObserverSubject, const nsAString& aSourceFile, bool aReportSample, const nsAString& aScriptSample, uint32_t aLineNum, uint32_t aColumnNum) { @@ -1565,8 +1644,8 @@ nsresult nsCSPContext::AsyncReportViolation( aTriggeringElement, aCSPEventListener, aBlockedURI, aBlockedContentSource, aOriginalURI, aViolatedPolicyIndex, mPolicies[aViolatedPolicyIndex]->getReportOnlyFlag(), aViolatedDirective, - aEffectiveDirective, aObserverSubject, aSourceFile, aReportSample, - aScriptSample, aLineNum, aColumnNum, this); + aViolatedDirectiveString, aEffectiveDirective, aObserverSubject, + aSourceFile, aReportSample, aScriptSample, aLineNum, aColumnNum, this); if (XRE_IsContentProcess()) { if (mEventTarget) { -- cgit v1.2.3