Skip to content

Commit

Permalink
Bug 1848315 - CSP: Provide the whole violated directive as a string. …
Browse files Browse the repository at this point in the history
…r=freddyb

Differential Revision: https://phabricator.services.mozilla.com/D186142
  • Loading branch information
Tom Schuster committed Mar 1, 2024
1 parent bb36594 commit e8b302c
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 59 deletions.
50 changes: 31 additions & 19 deletions dom/security/nsCSPContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down Expand Up @@ -220,7 +221,7 @@ bool nsCSPContext::permitsInternal(
BlockedContentSource::eUnknown, /* a BlockedContentSource */
aOriginalURIIfRedirect, /* in case of redirect originalURI is not
null */
violatedDirective,
violatedDirective, violatedDirectiveString,
aDir, // aViolatedDirective
p, // policy index
u""_ns, // no observer subject
Expand Down Expand Up @@ -515,7 +516,8 @@ void nsCSPContext::reportInlineViolation(
CSPDirective aDirective, Element* aTriggeringElement,
nsICSPEventListener* aCSPEventListener, const nsAString& aNonce,
bool aReportSample, const nsAString& aSample,
const nsAString& aViolatedDirective, CSPDirective 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;
Expand Down Expand Up @@ -560,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
Expand Down Expand Up @@ -668,13 +671,16 @@ nsCSPContext::GetAllowsInline(CSPDirective aDirective, bool aHasUnsafeHash,
*outAllowsInline = false;
}
nsAutoString violatedDirective;
nsAutoString violatedDirectiveString;
bool reportSample = false;
mPolicies[i]->getDirectiveStringAndReportSampleForContentType(
aDirective, violatedDirective, &reportSample);
mPolicies[i]->getViolatedDirectiveInformation(
aDirective, violatedDirective, violatedDirectiveString,
&reportSample);

reportInlineViolation(aDirective, aTriggeringElement, aCSPEventListener,
aNonce, reportSample, content, violatedDirective,
aDirective, i, aLineNumber, aColumnNumber);
violatedDirectiveString, aDirective, i, aLineNumber,
aColumnNumber);
}
}

Expand Down Expand Up @@ -737,13 +743,15 @@ 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,
nullptr, violatedDirective, violatedDirectiveString,
CSPDirective::SCRIPT_SRC_DIRECTIVE /* aEffectiveDirective */, p,
observerSubject, aSourceFile, reportSample, aScriptSample, aLineNum,
aColumnNum);
Expand Down Expand Up @@ -1367,6 +1375,7 @@ class CSPReportSenderRunnable final : public Runnable {
nsCSPContext::BlockedContentSource aBlockedContentSource,
nsIURI* aOriginalURI, uint32_t aViolatedPolicyIndex, bool aReportOnlyFlag,
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,
Expand All @@ -1381,6 +1390,7 @@ class CSPReportSenderRunnable final : public Runnable {
mReportOnlyFlag(aReportOnlyFlag),
mReportSample(aReportSample),
mViolatedDirective(aViolatedDirective),
mViolatedDirectiveString(aViolatedDirectiveString),
mEffectiveDirective(aEffectiveDirective),
mSourceFile(aSourceFile),
mScriptSample(aScriptSample),
Expand Down Expand Up @@ -1506,6 +1516,7 @@ class CSPReportSenderRunnable final : public Runnable {
bool mReportOnlyFlag;
bool mReportSample;
nsString mViolatedDirective;
nsString mViolatedDirectiveString;
CSPDirective mEffectiveDirective;
nsCOMPtr<nsISupports> mObserverSubject;
nsString mSourceFile;
Expand Down Expand Up @@ -1548,6 +1559,7 @@ nsresult nsCSPContext::AsyncReportViolation(
Element* aTriggeringElement, nsICSPEventListener* aCSPEventListener,
nsIURI* aBlockedURI, BlockedContentSource aBlockedContentSource,
nsIURI* aOriginalURI, const nsAString& aViolatedDirective,
const nsAString& aViolatedDirectiveString,
const CSPDirective aEffectiveDirective, uint32_t aViolatedPolicyIndex,
const nsAString& aObserverSubject, const nsAString& aSourceFile,
bool aReportSample, const nsAString& aScriptSample, uint32_t aLineNum,
Expand All @@ -1559,8 +1571,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) {
Expand Down
2 changes: 2 additions & 0 deletions dom/security/nsCSPContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ class nsCSPContext : public nsIContentSecurityPolicy {
nsICSPEventListener* aCSPEventListener, nsIURI* aBlockedURI,
BlockedContentSource aBlockedContentSource, nsIURI* aOriginalURI,
const nsAString& aViolatedDirective,
const nsAString& aViolatedDirectiveString,
const CSPDirective aEffectiveDirective, uint32_t aViolatedPolicyIndex,
const nsAString& aObserverSubject, const nsAString& aSourceFile,
bool aReportSample, const nsAString& aScriptSample, uint32_t aLineNum,
Expand Down Expand Up @@ -169,6 +170,7 @@ class nsCSPContext : public nsIContentSecurityPolicy {
const nsAString& aNonce, bool aReportSample,
const nsAString& aSample,
const nsAString& aViolatedDirective,
const nsAString& aViolatedDirectiveString,
CSPDirective aEffectiveDirective,
uint32_t aViolatedPolicyIndex,
uint32_t aLineNumber, uint32_t aColumnNumber);
Expand Down
51 changes: 17 additions & 34 deletions dom/security/nsCSPUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1569,7 +1569,8 @@ nsCSPPolicy::~nsCSPPolicy() {

bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,
nsIURI* aUri, bool aWasRedirected, bool aSpecific,
nsAString& outViolatedDirective) const {
nsAString& outViolatedDirective,
nsAString& outViolatedDirectiveString) const {
if (CSPUTILSLOGENABLED()) {
CSPUTILSLOG(("nsCSPPolicy::permits, aUri: %s, aDir: %s, aSpecific: %s",
aUri->GetSpecOrDefault().get(), CSP_CSPDirectiveToString(aDir),
Expand All @@ -1578,6 +1579,7 @@ bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,

NS_ASSERTION(aUri, "permits needs an uri to perform the check!");
outViolatedDirective.Truncate();
outViolatedDirectiveString.Truncate();

nsCSPDirective* defaultDir = nullptr;

Expand All @@ -1589,6 +1591,7 @@ bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,
if (!mDirectives[i]->permits(aDir, aLoadInfo, aUri, aWasRedirected,
mReportOnly, mUpgradeInsecDir)) {
mDirectives[i]->getDirName(outViolatedDirective);
mDirectives[i]->toString(outViolatedDirectiveString);
return false;
}
return true;
Expand All @@ -1604,6 +1607,7 @@ bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,
if (!defaultDir->permits(aDir, aLoadInfo, aUri, aWasRedirected, mReportOnly,
mUpgradeInsecDir)) {
defaultDir->getDirName(outViolatedDirective);
defaultDir->toString(outViolatedDirectiveString);
return false;
}
return true;
Expand Down Expand Up @@ -1692,43 +1696,22 @@ bool nsCSPPolicy::allowsAllInlineBehavior(CSPDirective aDir) const {
* The parameter outDirective is the equivalent of 'outViolatedDirective'
* for the ::permits() function family.
*/
void nsCSPPolicy::getDirectiveStringAndReportSampleForContentType(
CSPDirective aDirective, nsAString& outDirective,
bool* aReportSample) const {
MOZ_ASSERT(aReportSample);
void nsCSPPolicy::getViolatedDirectiveInformation(CSPDirective aDirective,
nsAString& outDirective,
nsAString& outDirectiveString,
bool* aReportSample) const {
*aReportSample = false;

nsCSPDirective* defaultDir = nullptr;
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
if (mDirectives[i]->isDefaultDirective()) {
defaultDir = mDirectives[i];
continue;
}
if (mDirectives[i]->equals(aDirective)) {
mDirectives[i]->getDirName(outDirective);
*aReportSample = mDirectives[i]->hasReportSampleKeyword();
return;
}
}
// if we haven't found a matching directive yet,
// the contentType must be restricted by the default directive
if (defaultDir) {
defaultDir->getDirName(outDirective);
*aReportSample = defaultDir->hasReportSampleKeyword();
nsCSPDirective* directive = matchingOrDefaultDirective(aDirective);
if (!directive) {
MOZ_ASSERT_UNREACHABLE("Can not query violated directive");
outDirective.AppendLiteral("couldNotQueryViolatedDirective");
outDirective.Truncate();
return;
}
NS_ASSERTION(false, "Can not query directive string for contentType!");
outDirective.AppendLiteral("couldNotQueryViolatedDirective");
}

void nsCSPPolicy::getDirectiveAsString(CSPDirective aDir,
nsAString& outDirective) const {
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
if (mDirectives[i]->equals(aDir)) {
mDirectives[i]->toString(outDirective);
return;
}
}
directive->getDirName(outDirective);
directive->toString(outDirectiveString);
*aReportSample = directive->hasReportSampleKeyword();
}

/*
Expand Down
12 changes: 6 additions & 6 deletions dom/security/nsCSPUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,8 @@ class nsCSPPolicy {

bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo, nsIURI* aUri,
bool aWasRedirected, bool aSpecific,
nsAString& outViolatedDirective) const;
nsAString& outViolatedDirective,
nsAString& outViolatedDirectiveString) const;
bool allows(CSPDirective aDirective, enum CSPKeyword aKeyword,
const nsAString& aHashOrNonce) const;
void toString(nsAString& outStr) const;
Expand Down Expand Up @@ -650,11 +651,10 @@ class nsCSPPolicy {

void getReportURIs(nsTArray<nsString>& outReportURIs) const;

void getDirectiveStringAndReportSampleForContentType(
CSPDirective aDirective, nsAString& outDirective,
bool* aReportSample) const;

void getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const;
void getViolatedDirectiveInformation(CSPDirective aDirective,
nsAString& outDirective,
nsAString& outDirectiveString,
bool* aReportSample) const;

uint32_t getSandboxFlags() const;

Expand Down

0 comments on commit e8b302c

Please sign in to comment.