зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1418243 - Fix SecurityPolicyViolationEvent.violatedDirective. r=ckerschb
MozReview-Commit-ID: 8DQ7CI5exUL
This commit is contained in:
Родитель
b246f6ad48
Коммит
eaddf31393
|
@ -4,6 +4,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -64,6 +67,29 @@ GetCspContextLog()
|
|||
|
||||
static const uint32_t CSP_CACHE_URI_CUTOFF_SIZE = 512;
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* This function is only used for verification purposes within
|
||||
* GatherSecurityPolicyViolationEventData.
|
||||
*/
|
||||
static bool
|
||||
ValidateDirectiveName(const nsAString& aDirective)
|
||||
{
|
||||
static const auto directives = [] () {
|
||||
std::unordered_set<std::string> directives;
|
||||
constexpr size_t dirLen = sizeof(CSPStrDirectives) / sizeof(CSPStrDirectives[0]);
|
||||
for (size_t i = 0; i < dirLen; ++i) {
|
||||
directives.insert(CSPStrDirectives[i]);
|
||||
}
|
||||
return directives;
|
||||
} ();
|
||||
|
||||
nsAutoString directive(aDirective);
|
||||
auto itr = directives.find(NS_ConvertUTF16toUTF8(directive).get());
|
||||
return itr != directives.end();
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
/**
|
||||
* Creates a key for use in the ShouldLoad cache.
|
||||
* Looks like: <uri>!<nsIContentPolicy::LOAD_TYPE>
|
||||
|
@ -869,6 +895,8 @@ nsCSPContext::GatherSecurityPolicyViolationEventData(
|
|||
{
|
||||
NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
|
||||
|
||||
MOZ_ASSERT(ValidateDirectiveName(aViolatedDirective), "Invalid directive name");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// document-uri
|
||||
|
@ -900,12 +928,15 @@ nsCSPContext::GatherSecurityPolicyViolationEventData(
|
|||
aViolationEventInit.mBlockedURI = NS_ConvertUTF8toUTF16(reportBlockedURI);
|
||||
}
|
||||
|
||||
// violated-directive
|
||||
aViolationEventInit.mViolatedDirective = aViolatedDirective;
|
||||
|
||||
// effective-directive
|
||||
// The name of the policy directive that was violated.
|
||||
aViolationEventInit.mEffectiveDirective = aViolatedDirective;
|
||||
|
||||
// violated-directive
|
||||
// In CSP2, the policy directive that was violated, as it appears in the policy.
|
||||
// In CSP3, the same as effective-directive.
|
||||
aViolationEventInit.mViolatedDirective = aViolatedDirective;
|
||||
|
||||
// original-policy
|
||||
nsAutoString originalPolicy;
|
||||
rv = this->GetPolicyString(aViolatedPolicyIndex, originalPolicy);
|
||||
|
@ -1216,18 +1247,21 @@ class CSPReportSenderRunnable final : public Runnable
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// 0) prepare violation data
|
||||
mozilla::dom::SecurityPolicyViolationEventInit init;
|
||||
mCSPContext->GatherSecurityPolicyViolationEventData(
|
||||
rv = mCSPContext->GatherSecurityPolicyViolationEventData(
|
||||
mBlockedContentSource, mOriginalURI,
|
||||
mViolatedDirective, mViolatedPolicyIndex,
|
||||
mSourceFile, mScriptSample, mLineNum,
|
||||
init);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// 1) notify observers
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
NS_ASSERTION(observerService, "needs observer service");
|
||||
nsresult rv = observerService->NotifyObservers(mObserverSubject,
|
||||
rv = observerService->NotifyObservers(mObserverSubject,
|
||||
CSP_VIOLATION_TOPIC,
|
||||
mViolatedDirective.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -1243,6 +1243,12 @@ bool nsCSPDirective::equals(CSPDirective aDirective) const
|
|||
return (mDirective == aDirective);
|
||||
}
|
||||
|
||||
void
|
||||
nsCSPDirective::getDirName(nsAString& outStr) const
|
||||
{
|
||||
outStr.AppendASCII(CSP_CSPDirectiveToString(mDirective));
|
||||
}
|
||||
|
||||
/* =============== nsCSPChildSrcDirective ============= */
|
||||
|
||||
nsCSPChildSrcDirective::nsCSPChildSrcDirective(CSPDirective aDirective)
|
||||
|
@ -1328,6 +1334,13 @@ nsBlockAllMixedContentDirective::toString(nsAString& outStr) const
|
|||
nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT));
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockAllMixedContentDirective::getDirName(nsAString& outStr) const
|
||||
{
|
||||
outStr.AppendASCII(CSP_CSPDirectiveToString(
|
||||
nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT));
|
||||
}
|
||||
|
||||
/* =============== nsUpgradeInsecureDirective ============= */
|
||||
|
||||
nsUpgradeInsecureDirective::nsUpgradeInsecureDirective(CSPDirective aDirective)
|
||||
|
@ -1346,6 +1359,13 @@ nsUpgradeInsecureDirective::toString(nsAString& outStr) const
|
|||
nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE));
|
||||
}
|
||||
|
||||
void
|
||||
nsUpgradeInsecureDirective::getDirName(nsAString& outStr) const
|
||||
{
|
||||
outStr.AppendASCII(CSP_CSPDirectiveToString(
|
||||
nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE));
|
||||
}
|
||||
|
||||
/* ===== nsRequireSRIForDirective ========================= */
|
||||
|
||||
nsRequireSRIForDirective::nsRequireSRIForDirective(CSPDirective aDirective)
|
||||
|
@ -1397,6 +1417,13 @@ nsRequireSRIForDirective::allows(enum CSPKeyword aKeyword, const nsAString& aHas
|
|||
return (aKeyword != CSP_REQUIRE_SRI_FOR);
|
||||
}
|
||||
|
||||
void
|
||||
nsRequireSRIForDirective::getDirName(nsAString& outStr) const
|
||||
{
|
||||
outStr.AppendASCII(CSP_CSPDirectiveToString(
|
||||
nsIContentSecurityPolicy::REQUIRE_SRI_FOR));
|
||||
}
|
||||
|
||||
/* ===== nsCSPPolicy ========================= */
|
||||
|
||||
nsCSPPolicy::nsCSPPolicy()
|
||||
|
@ -1450,7 +1477,7 @@ nsCSPPolicy::permits(CSPDirective aDir,
|
|||
if (mDirectives[i]->equals(aDir)) {
|
||||
if (!mDirectives[i]->permits(aUri, aNonce, aWasRedirected, mReportOnly,
|
||||
mUpgradeInsecDir, aParserCreated)) {
|
||||
mDirectives[i]->toString(outViolatedDirective);
|
||||
mDirectives[i]->getDirName(outViolatedDirective);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1465,7 +1492,7 @@ nsCSPPolicy::permits(CSPDirective aDir,
|
|||
if (!aSpecific && defaultDir) {
|
||||
if (!defaultDir->permits(aUri, aNonce, aWasRedirected, mReportOnly,
|
||||
mUpgradeInsecDir, aParserCreated)) {
|
||||
defaultDir->toString(outViolatedDirective);
|
||||
defaultDir->getDirName(outViolatedDirective);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1592,7 +1619,7 @@ nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType,
|
|||
nsCSPDirective* defaultDir = nullptr;
|
||||
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
|
||||
if (mDirectives[i]->restrictsContentType(aContentType)) {
|
||||
mDirectives[i]->toString(outDirective);
|
||||
mDirectives[i]->getDirName(outDirective);
|
||||
return;
|
||||
}
|
||||
if (mDirectives[i]->isDefaultDirective()) {
|
||||
|
@ -1602,7 +1629,7 @@ nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType,
|
|||
// if we haven't found a matching directive yet,
|
||||
// the contentType must be restricted by the default directive
|
||||
if (defaultDir) {
|
||||
defaultDir->toString(outDirective);
|
||||
defaultDir->getDirName(outDirective);
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(false, "Can not query directive string for contentType!");
|
||||
|
|
|
@ -471,6 +471,8 @@ class nsCSPDirective {
|
|||
|
||||
bool visitSrcs(nsCSPSrcVisitor* aVisitor) const;
|
||||
|
||||
virtual void getDirName(nsAString& outStr) const;
|
||||
|
||||
protected:
|
||||
CSPDirective mDirective;
|
||||
nsTArray<nsCSPBaseSrc*> mSrcs;
|
||||
|
@ -549,6 +551,8 @@ class nsBlockAllMixedContentDirective : public nsCSPDirective {
|
|||
|
||||
void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) override
|
||||
{ MOZ_ASSERT(false, "block-all-mixed-content does not hold any srcs"); }
|
||||
|
||||
void getDirName(nsAString& outStr) const override;
|
||||
};
|
||||
|
||||
/* =============== nsUpgradeInsecureDirective === */
|
||||
|
@ -602,6 +606,8 @@ class nsUpgradeInsecureDirective : public nsCSPDirective {
|
|||
|
||||
void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) override
|
||||
{ MOZ_ASSERT(false, "upgrade-insecure-requests does not hold any srcs"); }
|
||||
|
||||
void getDirName(nsAString& outStr) const override;
|
||||
};
|
||||
|
||||
/* ===== nsRequireSRIForDirective ========================= */
|
||||
|
@ -619,6 +625,7 @@ class nsRequireSRIForDirective : public nsCSPDirective {
|
|||
bool restrictsContentType(nsContentPolicyType aType) const override;
|
||||
bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
|
||||
bool aParserCreated) const override;
|
||||
void getDirName(nsAString& outStr) const override;
|
||||
|
||||
private:
|
||||
nsTArray<nsContentPolicyType> mTypes;
|
||||
|
|
Загрузка…
Ссылка в новой задаче