Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Unified Diff: third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp

Issue 2404373003: Experimental Feature: Allow-CSP-From header (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
index 86a6de795f9fbe57a540ea225dbbf16344474856..058402eeb43072087080f609b40fbd6f1881c566 100644
--- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -311,6 +311,48 @@ void ContentSecurityPolicy::didReceiveHeader(
applyPolicySideEffectsToExecutionContext();
}
+bool ContentSecurityPolicy::checkAllowBlanketEnforcement(
amalika 2016/10/11 19:06:46 This is the most important function. After I ran
+ const ResourceResponse& response,
+ const KURL& parentUrl) {
+ if (response.url().isEmpty() || response.url().protocolIsAbout() ||
+ response.url().protocolIsAbout() || response.url().protocolIs("blob") ||
+ response.url().protocolIs("filesystem")) {
+ return true;
+ }
+
+ if (parentUrl.protocol() == response.url().protocol() &&
+ parentUrl.host() == response.url().host() &&
+ parentUrl.port() == response.url().port()) {
+ return true;
+ }
+
+ HTTPHeaderMap::const_iterator it =
+ response.httpHeaderFields().find(HTTPNames::Allow_CSP_From);
+
+ String header =
+ it != response.httpHeaderFields().end() ? it->value : nullAtom;
+
+ if (header.isEmpty() || !header.containsOnlyASCII())
+ return false;
+
+ Vector<String> headers;
+ header.split(',', headers);
+ for (size_t i = 0; i < headers.size(); i++) {
+ String currentHeader = headers[i].stripWhiteSpace();
+ if (equalIgnoringCase(currentHeader, "*")) {
+ return true;
+ }
+ const KURL allowed(ParsedURLString, currentHeader);
+ if (allowed.isValid() && parentUrl.protocol() == allowed.protocol() &&
+ parentUrl.host() == allowed.host() &&
+ parentUrl.port() == allowed.port()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void ContentSecurityPolicy::addPolicyFromHeaderValue(
const String& header,
ContentSecurityPolicyHeaderType type,
@@ -357,1146 +399,1176 @@ void ContentSecurityPolicy::addPolicyFromHeaderValue(
skipExactly<UChar>(position, end, ',');
begin = position;
}
-}
-
-void ContentSecurityPolicy::reportAccumulatedHeaders(
- FrameLoaderClient* client) const {
- // Notify the embedder about headers that have accumulated before the
- // navigation got committed. See comments in
- // addAndReportPolicyFromHeaderValue for more details and context.
- DCHECK(client);
- for (const auto& policy : m_policies) {
- client->didAddContentSecurityPolicy(policy->header(), policy->headerType(),
- policy->headerSource());
}
-}
-void ContentSecurityPolicy::addAndReportPolicyFromHeaderValue(
- const String& header,
- ContentSecurityPolicyHeaderType type,
- ContentSecurityPolicyHeaderSource source) {
- // Notify about the new header, so that it can be reported back to the
- // browser process. This is needed in order to:
- // 1) replicate CSP directives (i.e. frame-src) to OOPIFs (only for now /
- // short-term).
- // 2) enforce CSP in the browser process (not yet / long-term - see
- // https://crbug.com/376522).
- if (document() && document()->frame())
- document()->frame()->client()->didAddContentSecurityPolicy(header, type,
- source);
-
- addPolicyFromHeaderValue(header, type, source);
-}
+ void ContentSecurityPolicy::reportAccumulatedHeaders(
+ FrameLoaderClient* client) const {
+ // Notify the embedder about headers that have accumulated before the
+ // navigation got committed. See comments in
+ // addAndReportPolicyFromHeaderValue for more details and context.
+ DCHECK(client);
+ for (const auto& policy : m_policies) {
+ client->didAddContentSecurityPolicy(
+ policy->header(), policy->headerType(), policy->headerSource());
+ }
+ }
-void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value) {
- m_overrideInlineStyleAllowed = value;
-}
+ void ContentSecurityPolicy::addAndReportPolicyFromHeaderValue(
+ const String& header,
+ ContentSecurityPolicyHeaderType type,
+ ContentSecurityPolicyHeaderSource source) {
+ // Notify about the new header, so that it can be reported back to the
+ // browser process. This is needed in order to:
+ // 1) replicate CSP directives (i.e. frame-src) to OOPIFs (only for now /
+ // short-term).
+ // 2) enforce CSP in the browser process (not yet / long-term - see
+ // https://crbug.com/376522).
+ if (document() && document()->frame()) {
+ document()->frame()->client()->didAddContentSecurityPolicy(header, type,
+ source);
+ }
-void ContentSecurityPolicy::setOverrideURLForSelf(const KURL& url) {
- // Create a temporary CSPSource so that 'self' expressions can be resolved
- // before we bind to an execution context (for 'frame-ancestor' resolution,
- // for example). This CSPSource will be overwritten when we bind this object
- // to an execution context.
- RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
- m_selfProtocol = origin->protocol();
- m_selfSource =
- new CSPSource(this, m_selfProtocol, origin->host(), origin->port(),
- String(), CSPSource::NoWildcard, CSPSource::NoWildcard);
-}
+ addPolicyFromHeaderValue(header, type, source);
+ }
-std::unique_ptr<Vector<CSPHeaderAndType>> ContentSecurityPolicy::headers()
- const {
- std::unique_ptr<Vector<CSPHeaderAndType>> headers =
- wrapUnique(new Vector<CSPHeaderAndType>);
- for (const auto& policy : m_policies) {
- CSPHeaderAndType headerAndType(policy->header(), policy->headerType());
- headers->append(headerAndType);
+ void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value) {
+ m_overrideInlineStyleAllowed = value;
}
- return headers;
-}
-template <bool (CSPDirectiveList::*allowed)(
- ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAll(const CSPDirectiveListVector& policies,
- ContentSecurityPolicy::ReportingStatus reportingStatus) {
- bool isAllowed = true;
- for (const auto& policy : policies)
- isAllowed &= (policy.get()->*allowed)(reportingStatus);
- return isAllowed;
-}
+ void ContentSecurityPolicy::setOverrideURLForSelf(const KURL& url) {
+ // Create a temporary CSPSource so that 'self' expressions can be resolved
+ // before we bind to an execution context (for 'frame-ancestor' resolution,
+ // for example). This CSPSource will be overwritten when we bind this object
+ // to an execution context.
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
+ m_selfProtocol = origin->protocol();
+ m_selfSource =
+ new CSPSource(this, m_selfProtocol, origin->host(), origin->port(),
+ String(), CSPSource::NoWildcard, CSPSource::NoWildcard);
+ }
-template <bool (CSPDirectiveList::*allowed)(
- ScriptState* scriptState,
- ContentSecurityPolicy::ReportingStatus,
- ContentSecurityPolicy::ExceptionStatus) const>
-bool isAllowedByAllWithStateAndExceptionStatus(
- const CSPDirectiveListVector& policies,
- ScriptState* scriptState,
- ContentSecurityPolicy::ReportingStatus reportingStatus,
- ContentSecurityPolicy::ExceptionStatus exceptionStatus) {
- bool isAllowed = true;
- for (const auto& policy : policies)
- isAllowed &=
- (policy.get()->*allowed)(scriptState, reportingStatus, exceptionStatus);
- return isAllowed;
-}
+ std::unique_ptr<Vector<CSPHeaderAndType>> ContentSecurityPolicy::headers()
+ const {
+ std::unique_ptr<Vector<CSPHeaderAndType>> headers =
+ wrapUnique(new Vector<CSPHeaderAndType>);
+ for (const auto& policy : m_policies) {
+ CSPHeaderAndType headerAndType(policy->header(), policy->headerType());
+ headers->append(headerAndType);
+ }
+ return headers;
+ }
-template <bool (CSPDirectiveList::*allowed)(
- const String&,
- const WTF::OrdinalNumber&,
- ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithContext(
- const CSPDirectiveListVector& policies,
- const String& contextURL,
- const WTF::OrdinalNumber& contextLine,
- ContentSecurityPolicy::ReportingStatus reportingStatus) {
- bool isAllowed = true;
- for (const auto& policy : policies)
- isAllowed &=
- (policy.get()->*allowed)(contextURL, contextLine, reportingStatus);
- return isAllowed;
-}
+ template <bool (CSPDirectiveList::*allowed)(
+ ContentSecurityPolicy::ReportingStatus) const>
+ bool isAllowedByAll(const CSPDirectiveListVector& policies,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) {
+ bool isAllowed = true;
+ for (const auto& policy : policies)
+ isAllowed &= (policy.get()->*allowed)(reportingStatus);
+ return isAllowed;
+ }
-template <
- bool (CSPDirectiveList::*allowed)(const String&,
- const String&,
- const WTF::OrdinalNumber&,
- ContentSecurityPolicy::ReportingStatus,
- const String& content) const>
-bool isAllowedByAllWithContextAndContent(
- const CSPDirectiveListVector& policies,
- const String& contextURL,
- const String& nonce,
- const WTF::OrdinalNumber& contextLine,
- ContentSecurityPolicy::ReportingStatus reportingStatus,
- const String& content) {
- bool isAllowed = true;
- for (const auto& policy : policies)
- isAllowed &= (policy.get()->*allowed)(contextURL, nonce, contextLine,
- reportingStatus, content);
- return isAllowed;
-}
+ template <bool (CSPDirectiveList::*allowed)(
+ ScriptState* scriptState,
+ ContentSecurityPolicy::ReportingStatus,
+ ContentSecurityPolicy::ExceptionStatus) const>
+ bool isAllowedByAllWithStateAndExceptionStatus(
+ const CSPDirectiveListVector& policies,
+ ScriptState* scriptState,
+ ContentSecurityPolicy::ReportingStatus reportingStatus,
+ ContentSecurityPolicy::ExceptionStatus exceptionStatus) {
+ bool isAllowed = true;
+ for (const auto& policy : policies) {
+ isAllowed &= (policy.get()->*allowed)(scriptState, reportingStatus,
+ exceptionStatus);
+ }
+ return isAllowed;
+ }
-template <
- bool (CSPDirectiveList::*allowed)(const String&,
- const String&,
- ParserDisposition,
- const WTF::OrdinalNumber&,
- ContentSecurityPolicy::ReportingStatus,
- const String& content) const>
-bool isAllowedByAllWithContextAndContentAndParser(
- const CSPDirectiveListVector& policies,
- const String& contextURL,
- const String& nonce,
- ParserDisposition parserDisposition,
- const WTF::OrdinalNumber& contextLine,
- ContentSecurityPolicy::ReportingStatus reportingStatus,
- const String& content) {
- bool isAllowed = true;
- for (const auto& policy : policies) {
- isAllowed &=
- (policy.get()->*allowed)(contextURL, nonce, parserDisposition,
- contextLine, reportingStatus, content);
- }
- return isAllowed;
-}
+ template <bool (CSPDirectiveList::*allowed)(
+ const String&,
+ const WTF::OrdinalNumber&,
+ ContentSecurityPolicy::ReportingStatus) const>
+ bool isAllowedByAllWithContext(
+ const CSPDirectiveListVector& policies,
+ const String& contextURL,
+ const WTF::OrdinalNumber& contextLine,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) {
+ bool isAllowed = true;
+ for (const auto& policy : policies) {
+ isAllowed &=
+ (policy.get()->*allowed)(contextURL, contextLine, reportingStatus);
+ }
+ return isAllowed;
+ }
-template <bool (CSPDirectiveList::*allowed)(const CSPHashValue&,
- ContentSecurityPolicy::InlineType)
- const>
-bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies,
- const CSPHashValue& hashValue,
- ContentSecurityPolicy::InlineType type) {
- bool isAllowed = true;
- for (const auto& policy : policies)
- isAllowed &= (policy.get()->*allowed)(hashValue, type);
- return isAllowed;
-}
+ template <
+ bool (CSPDirectiveList::*allowed)(const String&,
+ const String&,
+ const WTF::OrdinalNumber&,
+ ContentSecurityPolicy::ReportingStatus,
+ const String& content) const>
+ bool isAllowedByAllWithContextAndContent(
+ const CSPDirectiveListVector& policies,
+ const String& contextURL,
+ const String& nonce,
+ const WTF::OrdinalNumber& contextLine,
+ ContentSecurityPolicy::ReportingStatus reportingStatus,
+ const String& content) {
+ bool isAllowed = true;
+ for (const auto& policy : policies) {
+ isAllowed &= (policy.get()->*allowed)(contextURL, nonce, contextLine,
+ reportingStatus, content);
+ }
+ return isAllowed;
+ }
-template <bool (CSPDirectiveList::*allowFromURL)(
- const KURL&,
- RedirectStatus,
- ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithURL(
- const CSPDirectiveListVector& policies,
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) {
- if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
- return true;
+ template <
+ bool (CSPDirectiveList::*allowed)(const String&,
+ const String&,
+ ParserDisposition,
+ const WTF::OrdinalNumber&,
+ ContentSecurityPolicy::ReportingStatus,
+ const String& content) const>
+ bool isAllowedByAllWithContextAndContentAndParser(
+ const CSPDirectiveListVector& policies,
+ const String& contextURL,
+ const String& nonce,
+ ParserDisposition parserDisposition,
+ const WTF::OrdinalNumber& contextLine,
+ ContentSecurityPolicy::ReportingStatus reportingStatus,
+ const String& content) {
+ bool isAllowed = true;
+ for (const auto& policy : policies) {
+ isAllowed &=
+ (policy.get()->*allowed)(contextURL, nonce, parserDisposition,
+ contextLine, reportingStatus, content);
+ }
+ return isAllowed;
+ }
- bool isAllowed = true;
- for (const auto& policy : policies)
- isAllowed &=
- (policy.get()->*allowFromURL)(url, redirectStatus, reportingStatus);
- return isAllowed;
-}
+ template <bool (CSPDirectiveList::*allowed)(const CSPHashValue&,
+ ContentSecurityPolicy::InlineType)
+ const>
+ bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies,
+ const CSPHashValue& hashValue,
+ ContentSecurityPolicy::InlineType type) {
+ bool isAllowed = true;
+ for (const auto& policy : policies)
+ isAllowed &= (policy.get()->*allowed)(hashValue, type);
+ return isAllowed;
+ }
-template <bool (CSPDirectiveList::*allowFromURLWithNonce)(
- const KURL&,
- const String& nonce,
- RedirectStatus,
- ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithURLWithNonce(
- const CSPDirectiveListVector& policies,
- const KURL& url,
- const String& nonce,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) {
- if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
- return true;
+ template <bool (CSPDirectiveList::*allowFromURL)(
+ const KURL&,
+ RedirectStatus,
+ ContentSecurityPolicy::ReportingStatus) const>
+ bool isAllowedByAllWithURL(
+ const CSPDirectiveListVector& policies,
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) {
+ if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+ return true;
- bool isAllowed = true;
- for (const auto& policy : policies)
- isAllowed &= (policy.get()->*allowFromURLWithNonce)(
- url, nonce, redirectStatus, reportingStatus);
- return isAllowed;
-}
+ bool isAllowed = true;
+ for (const auto& policy : policies) {
+ isAllowed &=
+ (policy.get()->*allowFromURL)(url, redirectStatus, reportingStatus);
+ }
+ return isAllowed;
+ }
-template <bool (CSPDirectiveList::*allowFromURLWithNonceAndParser)(
- const KURL&,
- const String& nonce,
- ParserDisposition parserDisposition,
- RedirectStatus,
- ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithURLNonceAndParser(
- const CSPDirectiveListVector& policies,
- const KURL& url,
- const String& nonce,
- ParserDisposition parserDisposition,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) {
- if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
- return true;
+ template <bool (CSPDirectiveList::*allowFromURLWithNonce)(
+ const KURL&,
+ const String& nonce,
+ RedirectStatus,
+ ContentSecurityPolicy::ReportingStatus) const>
+ bool isAllowedByAllWithURLWithNonce(
+ const CSPDirectiveListVector& policies,
+ const KURL& url,
+ const String& nonce,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) {
+ if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+ return true;
- bool isAllowed = true;
- for (const auto& policy : policies) {
- isAllowed &= (policy.get()->*allowFromURLWithNonceAndParser)(
- url, nonce, parserDisposition, redirectStatus, reportingStatus);
+ bool isAllowed = true;
+ for (const auto& policy : policies) {
+ isAllowed &= (policy.get()->*allowFromURLWithNonce)(
+ url, nonce, redirectStatus, reportingStatus);
+ }
+ return isAllowed;
}
- return isAllowed;
-}
-template <bool (CSPDirectiveList::*allowed)(
- LocalFrame*,
- const KURL&,
- ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithFrame(
- const CSPDirectiveListVector& policies,
- LocalFrame* frame,
- const KURL& url,
- ContentSecurityPolicy::ReportingStatus reportingStatus) {
- bool isAllowed = true;
- for (const auto& policy : policies)
- isAllowed &= (policy.get()->*allowed)(frame, url, reportingStatus);
- return isAllowed;
-}
-
-template <bool (CSPDirectiveList::*allowed)(const CSPHashValue&,
- ContentSecurityPolicy::InlineType)
- const>
-bool checkDigest(const String& source,
- ContentSecurityPolicy::InlineType type,
- uint8_t hashAlgorithmsUsed,
- const CSPDirectiveListVector& policies) {
- // Any additions or subtractions from this struct should also modify the
- // respective entries in the kSupportedPrefixes array in
- // CSPSourceList::parseHash().
- static const struct {
- ContentSecurityPolicyHashAlgorithm cspHashAlgorithm;
- HashAlgorithm algorithm;
- } kAlgorithmMap[] = {
- {ContentSecurityPolicyHashAlgorithmSha1, HashAlgorithmSha1},
- {ContentSecurityPolicyHashAlgorithmSha256, HashAlgorithmSha256},
- {ContentSecurityPolicyHashAlgorithmSha384, HashAlgorithmSha384},
- {ContentSecurityPolicyHashAlgorithmSha512, HashAlgorithmSha512}};
-
- // Only bother normalizing the source/computing digests if there are any
- // checks to be done.
- if (hashAlgorithmsUsed == ContentSecurityPolicyHashAlgorithmNone)
- return false;
+ template <bool (CSPDirectiveList::*allowFromURLWithNonceAndParser)(
+ const KURL&,
+ const String& nonce,
+ ParserDisposition parserDisposition,
+ RedirectStatus,
+ ContentSecurityPolicy::ReportingStatus) const>
+ bool isAllowedByAllWithURLNonceAndParser(
+ const CSPDirectiveListVector& policies,
+ const KURL& url,
+ const String& nonce,
+ ParserDisposition parserDisposition,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) {
+ if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+ return true;
- StringUTF8Adaptor utf8Source(source);
-
- for (const auto& algorithmMap : kAlgorithmMap) {
- DigestValue digest;
- if (algorithmMap.cspHashAlgorithm & hashAlgorithmsUsed) {
- bool digestSuccess =
- computeDigest(algorithmMap.algorithm, utf8Source.data(),
- utf8Source.length(), digest);
- if (digestSuccess &&
- isAllowedByAllWithHash<allowed>(
- policies, CSPHashValue(algorithmMap.cspHashAlgorithm, digest),
- type))
- return true;
+ bool isAllowed = true;
+ for (const auto& policy : policies) {
+ isAllowed &= (policy.get()->*allowFromURLWithNonceAndParser)(
+ url, nonce, parserDisposition, redirectStatus, reportingStatus);
}
+ return isAllowed;
}
- return false;
-}
-
-bool ContentSecurityPolicy::allowJavaScriptURLs(
- const String& contextURL,
- const WTF::OrdinalNumber& contextLine,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(
- m_policies, contextURL, contextLine, reportingStatus);
-}
+ template <bool (CSPDirectiveList::*allowed)(
+ LocalFrame*,
+ const KURL&,
+ ContentSecurityPolicy::ReportingStatus) const>
+ bool isAllowedByAllWithFrame(
+ const CSPDirectiveListVector& policies,
+ LocalFrame* frame,
+ const KURL& url,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) {
+ bool isAllowed = true;
+ for (const auto& policy : policies)
+ isAllowed &= (policy.get()->*allowed)(frame, url, reportingStatus);
+ return isAllowed;
+ }
-bool ContentSecurityPolicy::allowInlineEventHandler(
- const String& source,
- const String& contextURL,
- const WTF::OrdinalNumber& contextLine,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- // Inline event handlers may be whitelisted by hash, if
- // 'unsafe-hash-attributes' is present in a policy. Check against the digest
- // of the |source| first before proceeding on to checking whether inline
- // script is allowed.
- if (checkDigest<&CSPDirectiveList::allowScriptHash>(
- source, InlineType::Attribute, m_scriptHashAlgorithmsUsed,
- m_policies))
- return true;
- return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(
- m_policies, contextURL, contextLine, reportingStatus);
-}
+ template <bool (CSPDirectiveList::*allowed)(const CSPHashValue&,
+ ContentSecurityPolicy::InlineType)
+ const>
+ bool checkDigest(const String& source,
+ ContentSecurityPolicy::InlineType type,
+ uint8_t hashAlgorithmsUsed,
+ const CSPDirectiveListVector& policies) {
+ // Any additions or subtractions from this struct should also modify the
+ // respective entries in the kSupportedPrefixes array in
+ // CSPSourceList::parseHash().
+ static const struct {
+ ContentSecurityPolicyHashAlgorithm cspHashAlgorithm;
+ HashAlgorithm algorithm;
+ } kAlgorithmMap[] = {
+ {ContentSecurityPolicyHashAlgorithmSha1, HashAlgorithmSha1},
+ {ContentSecurityPolicyHashAlgorithmSha256, HashAlgorithmSha256},
+ {ContentSecurityPolicyHashAlgorithmSha384, HashAlgorithmSha384},
+ {ContentSecurityPolicyHashAlgorithmSha512, HashAlgorithmSha512}};
+
+ // Only bother normalizing the source/computing digests if there are any
+ // checks to be done.
+ if (hashAlgorithmsUsed == ContentSecurityPolicyHashAlgorithmNone)
+ return false;
-bool ContentSecurityPolicy::allowInlineScript(
- const String& contextURL,
- const String& nonce,
- ParserDisposition parserDisposition,
- const WTF::OrdinalNumber& contextLine,
- const String& scriptContent,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithContextAndContentAndParser<
- &CSPDirectiveList::allowInlineScript>(m_policies, contextURL, nonce,
- parserDisposition, contextLine,
- reportingStatus, scriptContent);
-}
+ StringUTF8Adaptor utf8Source(source);
+
+ for (const auto& algorithmMap : kAlgorithmMap) {
+ DigestValue digest;
+ if (algorithmMap.cspHashAlgorithm & hashAlgorithmsUsed) {
+ bool digestSuccess =
+ computeDigest(algorithmMap.algorithm, utf8Source.data(),
+ utf8Source.length(), digest);
+ if (digestSuccess &&
+ isAllowedByAllWithHash<allowed>(
+ policies, CSPHashValue(algorithmMap.cspHashAlgorithm, digest),
+ type))
+ return true;
+ }
+ }
-bool ContentSecurityPolicy::allowInlineStyle(
- const String& contextURL,
- const String& nonce,
- const WTF::OrdinalNumber& contextLine,
- const String& styleContent,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- if (m_overrideInlineStyleAllowed)
- return true;
- return isAllowedByAllWithContextAndContent<
- &CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, nonce,
- contextLine, reportingStatus,
- styleContent);
-}
+ return false;
+ }
-bool ContentSecurityPolicy::allowEval(
- ScriptState* scriptState,
- ContentSecurityPolicy::ReportingStatus reportingStatus,
- ContentSecurityPolicy::ExceptionStatus exceptionStatus) const {
- return isAllowedByAllWithStateAndExceptionStatus<
- &CSPDirectiveList::allowEval>(m_policies, scriptState, reportingStatus,
- exceptionStatus);
-}
+ bool ContentSecurityPolicy::allowJavaScriptURLs(
+ const String& contextURL,
+ const WTF::OrdinalNumber& contextLine,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(
+ m_policies, contextURL, contextLine, reportingStatus);
+ }
-String ContentSecurityPolicy::evalDisabledErrorMessage() const {
- for (const auto& policy : m_policies) {
- if (!policy->allowEval(0, SuppressReport))
- return policy->evalDisabledErrorMessage();
+ bool ContentSecurityPolicy::allowInlineEventHandler(
+ const String& source,
+ const String& contextURL,
+ const WTF::OrdinalNumber& contextLine,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ // Inline event handlers may be whitelisted by hash, if
+ // 'unsafe-hash-attributes' is present in a policy. Check against the digest
+ // of the |source| first before proceeding on to checking whether inline
+ // script is allowed.
+ if (checkDigest<&CSPDirectiveList::allowScriptHash>(
+ source, InlineType::Attribute, m_scriptHashAlgorithmsUsed,
+ m_policies))
+ return true;
+ return isAllowedByAllWithContext<
+ &CSPDirectiveList::allowInlineEventHandlers>(
+ m_policies, contextURL, contextLine, reportingStatus);
}
- return String();
-}
-bool ContentSecurityPolicy::allowPluginType(
- const String& type,
- const String& typeAttribute,
- const KURL& url,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- for (const auto& policy : m_policies) {
- if (!policy->allowPluginType(type, typeAttribute, url, reportingStatus))
- return false;
+ bool ContentSecurityPolicy::allowInlineScript(
+ const String& contextURL,
+ const String& nonce,
+ ParserDisposition parserDisposition,
+ const WTF::OrdinalNumber& contextLine,
+ const String& scriptContent,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithContextAndContentAndParser<
+ &CSPDirectiveList::allowInlineScript>(m_policies, contextURL, nonce,
+ parserDisposition, contextLine,
+ reportingStatus, scriptContent);
}
- return true;
-}
-bool ContentSecurityPolicy::allowPluginTypeForDocument(
- const Document& document,
- const String& type,
- const String& typeAttribute,
- const KURL& url,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- if (document.contentSecurityPolicy() &&
- !document.contentSecurityPolicy()->allowPluginType(type, typeAttribute,
- url))
- return false;
+ bool ContentSecurityPolicy::allowInlineStyle(
+ const String& contextURL,
+ const String& nonce,
+ const WTF::OrdinalNumber& contextLine,
+ const String& styleContent,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ if (m_overrideInlineStyleAllowed)
+ return true;
+ return isAllowedByAllWithContextAndContent<
+ &CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, nonce,
+ contextLine, reportingStatus,
+ styleContent);
+ }
- // CSP says that a plugin document in a nested browsing context should
- // inherit the plugin-types of its parent.
- //
- // FIXME: The plugin-types directive should be pushed down into the
- // current document instead of reaching up to the parent for it here.
- LocalFrame* frame = document.frame();
- if (frame && frame->tree().parent() && document.isPluginDocument()) {
- ContentSecurityPolicy* parentCSP =
- frame->tree().parent()->securityContext()->contentSecurityPolicy();
- if (parentCSP && !parentCSP->allowPluginType(type, typeAttribute, url))
- return false;
+ bool ContentSecurityPolicy::allowEval(
+ ScriptState* scriptState,
+ ContentSecurityPolicy::ReportingStatus reportingStatus,
+ ContentSecurityPolicy::ExceptionStatus exceptionStatus) const {
+ return isAllowedByAllWithStateAndExceptionStatus<
+ &CSPDirectiveList::allowEval>(m_policies, scriptState, reportingStatus,
+ exceptionStatus);
}
- return true;
-}
+ String ContentSecurityPolicy::evalDisabledErrorMessage() const {
+ for (const auto& policy : m_policies) {
+ if (!policy->allowEval(0, SuppressReport))
+ return policy->evalDisabledErrorMessage();
+ }
+ return String();
+ }
-bool ContentSecurityPolicy::allowScriptFromSource(
- const KURL& url,
- const String& nonce,
- ParserDisposition parserDisposition,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURLNonceAndParser<
- &CSPDirectiveList::allowScriptFromSource>(
- m_policies, url, nonce, parserDisposition, redirectStatus,
- reportingStatus);
-}
+ bool ContentSecurityPolicy::allowPluginType(
+ const String& type,
+ const String& typeAttribute,
+ const KURL& url,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ for (const auto& policy : m_policies) {
+ if (!policy->allowPluginType(type, typeAttribute, url, reportingStatus))
+ return false;
+ }
+ return true;
+ }
-bool ContentSecurityPolicy::allowScriptWithHash(const String& source,
- InlineType type) const {
- return checkDigest<&CSPDirectiveList::allowScriptHash>(
- source, type, m_scriptHashAlgorithmsUsed, m_policies);
-}
+ bool ContentSecurityPolicy::allowPluginTypeForDocument(
+ const Document& document,
+ const String& type,
+ const String& typeAttribute,
+ const KURL& url,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ if (document.contentSecurityPolicy() &&
+ !document.contentSecurityPolicy()->allowPluginType(type, typeAttribute,
+ url))
+ return false;
-bool ContentSecurityPolicy::allowStyleWithHash(const String& source,
- InlineType type) const {
- return checkDigest<&CSPDirectiveList::allowStyleHash>(
- source, type, m_styleHashAlgorithmsUsed, m_policies);
-}
+ // CSP says that a plugin document in a nested browsing context should
+ // inherit the plugin-types of its parent.
+ //
+ // FIXME: The plugin-types directive should be pushed down into the
+ // current document instead of reaching up to the parent for it here.
+ LocalFrame* frame = document.frame();
+ if (frame && frame->tree().parent() && document.isPluginDocument()) {
+ ContentSecurityPolicy* parentCSP =
+ frame->tree().parent()->securityContext()->contentSecurityPolicy();
+ if (parentCSP && !parentCSP->allowPluginType(type, typeAttribute, url))
+ return false;
+ }
-bool ContentSecurityPolicy::allowRequestWithoutIntegrity(
- WebURLRequest::RequestContext context,
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- for (const auto& policy : m_policies) {
- if (!policy->allowRequestWithoutIntegrity(context, url, redirectStatus,
- reportingStatus))
- return false;
+ return true;
}
- return true;
-}
-
-bool ContentSecurityPolicy::allowRequest(
- WebURLRequest::RequestContext context,
- const KURL& url,
- const String& nonce,
- const IntegrityMetadataSet& integrityMetadata,
- ParserDisposition parserDisposition,
- RedirectStatus redirectStatus,
- ReportingStatus reportingStatus) const {
- if (integrityMetadata.isEmpty() &&
- !allowRequestWithoutIntegrity(context, url, redirectStatus,
- reportingStatus))
- return false;
- switch (context) {
- case WebURLRequest::RequestContextAudio:
- case WebURLRequest::RequestContextTrack:
- case WebURLRequest::RequestContextVideo:
- return allowMediaFromSource(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextBeacon:
- case WebURLRequest::RequestContextEventSource:
- case WebURLRequest::RequestContextFetch:
- case WebURLRequest::RequestContextXMLHttpRequest:
- return allowConnectToSource(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextEmbed:
- case WebURLRequest::RequestContextObject:
- return allowObjectFromSource(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextFavicon:
- case WebURLRequest::RequestContextImage:
- case WebURLRequest::RequestContextImageSet:
- return allowImageFromSource(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextFont:
- return allowFontFromSource(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextForm:
- return allowFormAction(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextFrame:
- case WebURLRequest::RequestContextIframe:
- return allowChildFrameFromSource(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextImport:
- case WebURLRequest::RequestContextScript:
- return allowScriptFromSource(url, nonce, parserDisposition,
- redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextXSLT:
- return allowScriptFromSource(url, nonce, parserDisposition,
- redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextManifest:
- return allowManifestFromSource(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextServiceWorker:
- case WebURLRequest::RequestContextSharedWorker:
- case WebURLRequest::RequestContextWorker:
- return allowWorkerContextFromSource(url, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextStyle:
- return allowStyleFromSource(url, nonce, redirectStatus, reportingStatus);
- case WebURLRequest::RequestContextCSPReport:
- case WebURLRequest::RequestContextDownload:
- case WebURLRequest::RequestContextHyperlink:
- case WebURLRequest::RequestContextInternal:
- case WebURLRequest::RequestContextLocation:
- case WebURLRequest::RequestContextPing:
- case WebURLRequest::RequestContextPlugin:
- case WebURLRequest::RequestContextPrefetch:
- case WebURLRequest::RequestContextSubresource:
- case WebURLRequest::RequestContextUnspecified:
- return true;
+ bool ContentSecurityPolicy::allowScriptFromSource(
+ const KURL& url,
+ const String& nonce,
+ ParserDisposition parserDisposition,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURLNonceAndParser<
+ &CSPDirectiveList::allowScriptFromSource>(
+ m_policies, url, nonce, parserDisposition, redirectStatus,
+ reportingStatus);
}
- ASSERT_NOT_REACHED();
- return true;
-}
-void ContentSecurityPolicy::usesScriptHashAlgorithms(uint8_t algorithms) {
- m_scriptHashAlgorithmsUsed |= algorithms;
-}
+ bool ContentSecurityPolicy::allowScriptWithHash(const String& source,
+ InlineType type) const {
+ return checkDigest<&CSPDirectiveList::allowScriptHash>(
+ source, type, m_scriptHashAlgorithmsUsed, m_policies);
+ }
-void ContentSecurityPolicy::usesStyleHashAlgorithms(uint8_t algorithms) {
- m_styleHashAlgorithmsUsed |= algorithms;
-}
+ bool ContentSecurityPolicy::allowStyleWithHash(const String& source,
+ InlineType type) const {
+ return checkDigest<&CSPDirectiveList::allowStyleHash>(
+ source, type, m_styleHashAlgorithmsUsed, m_policies);
+ }
-bool ContentSecurityPolicy::allowObjectFromSource(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowRequestWithoutIntegrity(
+ WebURLRequest::RequestContext context,
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ for (const auto& policy : m_policies) {
+ if (!policy->allowRequestWithoutIntegrity(context, url, redirectStatus,
+ reportingStatus))
+ return false;
+ }
+ return true;
+ }
-bool ContentSecurityPolicy::allowChildFrameFromSource(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowRequest(
+ WebURLRequest::RequestContext context,
+ const KURL& url,
+ const String& nonce,
+ const IntegrityMetadataSet& integrityMetadata,
+ ParserDisposition parserDisposition,
+ RedirectStatus redirectStatus,
+ ReportingStatus reportingStatus) const {
+ if (integrityMetadata.isEmpty() &&
+ !allowRequestWithoutIntegrity(context, url, redirectStatus,
+ reportingStatus))
+ return false;
-bool ContentSecurityPolicy::allowImageFromSource(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
- url.protocol(), SchemeRegistry::PolicyAreaImage))
+ switch (context) {
+ case WebURLRequest::RequestContextAudio:
+ case WebURLRequest::RequestContextTrack:
+ case WebURLRequest::RequestContextVideo:
+ return allowMediaFromSource(url, redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextBeacon:
+ case WebURLRequest::RequestContextEventSource:
+ case WebURLRequest::RequestContextFetch:
+ case WebURLRequest::RequestContextXMLHttpRequest:
+ return allowConnectToSource(url, redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextEmbed:
+ case WebURLRequest::RequestContextObject:
+ return allowObjectFromSource(url, redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextFavicon:
+ case WebURLRequest::RequestContextImage:
+ case WebURLRequest::RequestContextImageSet:
+ return allowImageFromSource(url, redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextFont:
+ return allowFontFromSource(url, redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextForm:
+ return allowFormAction(url, redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextFrame:
+ case WebURLRequest::RequestContextIframe:
+ return allowChildFrameFromSource(url, redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextImport:
+ case WebURLRequest::RequestContextScript:
+ return allowScriptFromSource(url, nonce, parserDisposition,
+ redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextXSLT:
+ return allowScriptFromSource(url, nonce, parserDisposition,
+ redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextManifest:
+ return allowManifestFromSource(url, redirectStatus, reportingStatus);
+ case WebURLRequest::RequestContextServiceWorker:
+ case WebURLRequest::RequestContextSharedWorker:
+ case WebURLRequest::RequestContextWorker:
+ return allowWorkerContextFromSource(url, redirectStatus,
+ reportingStatus);
+ case WebURLRequest::RequestContextStyle:
+ return allowStyleFromSource(url, nonce, redirectStatus,
+ reportingStatus);
+ case WebURLRequest::RequestContextCSPReport:
+ case WebURLRequest::RequestContextDownload:
+ case WebURLRequest::RequestContextHyperlink:
+ case WebURLRequest::RequestContextInternal:
+ case WebURLRequest::RequestContextLocation:
+ case WebURLRequest::RequestContextPing:
+ case WebURLRequest::RequestContextPlugin:
+ case WebURLRequest::RequestContextPrefetch:
+ case WebURLRequest::RequestContextSubresource:
+ case WebURLRequest::RequestContextUnspecified:
+ return true;
+ }
+ NOTREACHED();
return true;
- return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ }
-bool ContentSecurityPolicy::allowStyleFromSource(
- const KURL& url,
- const String& nonce,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
- url.protocol(), SchemeRegistry::PolicyAreaStyle))
- return true;
- return isAllowedByAllWithURLWithNonce<
- &CSPDirectiveList::allowStyleFromSource>(m_policies, url, nonce,
- redirectStatus, reportingStatus);
-}
+ void ContentSecurityPolicy::usesScriptHashAlgorithms(uint8_t algorithms) {
+ m_scriptHashAlgorithmsUsed |= algorithms;
+ }
-bool ContentSecurityPolicy::allowFontFromSource(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ void ContentSecurityPolicy::usesStyleHashAlgorithms(uint8_t algorithms) {
+ m_styleHashAlgorithmsUsed |= algorithms;
+ }
-bool ContentSecurityPolicy::allowMediaFromSource(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowObjectFromSource(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(
+ m_policies, url, redirectStatus, reportingStatus);
+ }
-bool ContentSecurityPolicy::allowConnectToSource(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowChildFrameFromSource(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(
+ m_policies, url, redirectStatus, reportingStatus);
+ }
-bool ContentSecurityPolicy::allowFormAction(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURL<&CSPDirectiveList::allowFormAction>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowImageFromSource(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
+ url.protocol(), SchemeRegistry::PolicyAreaImage))
+ return true;
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(
+ m_policies, url, redirectStatus, reportingStatus);
+ }
-bool ContentSecurityPolicy::allowBaseURI(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowStyleFromSource(
+ const KURL& url,
+ const String& nonce,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
+ url.protocol(), SchemeRegistry::PolicyAreaStyle))
+ return true;
+ return isAllowedByAllWithURLWithNonce<
+ &CSPDirectiveList::allowStyleFromSource>(
+ m_policies, url, nonce, redirectStatus, reportingStatus);
+ }
-bool ContentSecurityPolicy::allowWorkerContextFromSource(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- // CSP 1.1 moves workers from 'script-src' to the new 'child-src'. Measure the
- // impact of this backwards-incompatible change.
- if (Document* document = this->document()) {
- UseCounter::count(*document, UseCounter::WorkerSubjectToCSP);
- if (isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(
- m_policies, url, redirectStatus, SuppressReport) &&
- !isAllowedByAllWithURLNonceAndParser<
- &CSPDirectiveList::allowScriptFromSource>(
- m_policies, url, AtomicString(), NotParserInserted, redirectStatus,
- SuppressReport)) {
- UseCounter::count(*document,
- UseCounter::WorkerAllowedByChildBlockedByScript);
- }
+ bool ContentSecurityPolicy::allowFontFromSource(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(
+ m_policies, url, redirectStatus, reportingStatus);
}
- return isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowMediaFromSource(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(
+ m_policies, url, redirectStatus, reportingStatus);
+ }
-bool ContentSecurityPolicy::allowManifestFromSource(
- const KURL& url,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithURL<&CSPDirectiveList::allowManifestFromSource>(
- m_policies, url, redirectStatus, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowConnectToSource(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(
+ m_policies, url, redirectStatus, reportingStatus);
+ }
-bool ContentSecurityPolicy::allowAncestors(
- LocalFrame* frame,
- const KURL& url,
- ContentSecurityPolicy::ReportingStatus reportingStatus) const {
- return isAllowedByAllWithFrame<&CSPDirectiveList::allowAncestors>(
- m_policies, frame, url, reportingStatus);
-}
+ bool ContentSecurityPolicy::allowFormAction(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowFormAction>(
+ m_policies, url, redirectStatus, reportingStatus);
+ }
-bool ContentSecurityPolicy::isFrameAncestorsEnforced() const {
- for (const auto& policy : m_policies) {
- if (policy->isFrameAncestorsEnforced())
- return true;
+ bool ContentSecurityPolicy::allowBaseURI(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(
+ m_policies, url, redirectStatus, reportingStatus);
}
- return false;
-}
-bool ContentSecurityPolicy::isActive() const {
- return !m_policies.isEmpty();
-}
+ bool ContentSecurityPolicy::allowWorkerContextFromSource(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ // CSP 1.1 moves workers from 'script-src' to the new 'child-src'. Measure
+ // the
+ // impact of this backwards-incompatible change.
+ if (Document* document = this->document()) {
+ UseCounter::count(*document, UseCounter::WorkerSubjectToCSP);
+ if (isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(
+ m_policies, url, redirectStatus, SuppressReport) &&
+ !isAllowedByAllWithURLNonceAndParser<
+ &CSPDirectiveList::allowScriptFromSource>(
+ m_policies, url, AtomicString(), NotParserInserted,
+ redirectStatus, SuppressReport)) {
+ UseCounter::count(*document,
+ UseCounter::WorkerAllowedByChildBlockedByScript);
+ }
+ }
-ReflectedXSSDisposition ContentSecurityPolicy::getReflectedXSSDisposition()
- const {
- ReflectedXSSDisposition disposition = ReflectedXSSUnset;
- for (const auto& policy : m_policies) {
- if (policy->getReflectedXSSDisposition() > disposition)
- disposition = std::max(disposition, policy->getReflectedXSSDisposition());
+ return isAllowedByAllWithURL<
+ &CSPDirectiveList::allowChildContextFromSource>(
+ m_policies, url, redirectStatus, reportingStatus);
}
- return disposition;
-}
-bool ContentSecurityPolicy::didSetReferrerPolicy() const {
- for (const auto& policy : m_policies) {
- if (policy->didSetReferrerPolicy())
- return true;
+ bool ContentSecurityPolicy::allowManifestFromSource(
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowManifestFromSource>(
+ m_policies, url, redirectStatus, reportingStatus);
}
- return false;
-}
-const KURL ContentSecurityPolicy::url() const {
- return m_executionContext->contextURL();
-}
+ bool ContentSecurityPolicy::allowAncestors(
+ LocalFrame* frame,
+ const KURL& url,
+ ContentSecurityPolicy::ReportingStatus reportingStatus) const {
+ return isAllowedByAllWithFrame<&CSPDirectiveList::allowAncestors>(
+ m_policies, frame, url, reportingStatus);
+ }
-KURL ContentSecurityPolicy::completeURL(const String& url) const {
- return m_executionContext->contextCompleteURL(url);
-}
+ bool ContentSecurityPolicy::isFrameAncestorsEnforced() const {
+ for (const auto& policy : m_policies) {
+ if (policy->isFrameAncestorsEnforced())
+ return true;
+ }
+ return false;
+ }
-void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) {
- m_sandboxMask |= mask;
-}
+ bool ContentSecurityPolicy::isActive() const {
+ return !m_policies.isEmpty();
+ }
-void ContentSecurityPolicy::treatAsPublicAddress() {
- if (!RuntimeEnabledFeatures::corsRFC1918Enabled())
- return;
- m_treatAsPublicAddress = true;
-}
+ ReflectedXSSDisposition ContentSecurityPolicy::getReflectedXSSDisposition()
+ const {
+ ReflectedXSSDisposition disposition = ReflectedXSSUnset;
+ for (const auto& policy : m_policies) {
+ if (policy->getReflectedXSSDisposition() > disposition) {
+ disposition =
+ std::max(disposition, policy->getReflectedXSSDisposition());
+ }
+ }
+ return disposition;
+ }
-void ContentSecurityPolicy::enforceStrictMixedContentChecking() {
- m_insecureRequestPolicy |= kBlockAllMixedContent;
-}
+ bool ContentSecurityPolicy::didSetReferrerPolicy() const {
+ for (const auto& policy : m_policies) {
+ if (policy->didSetReferrerPolicy())
+ return true;
+ }
+ return false;
+ }
-void ContentSecurityPolicy::upgradeInsecureRequests() {
- m_insecureRequestPolicy |= kUpgradeInsecureRequests;
-}
+ const KURL ContentSecurityPolicy::url() const {
+ return m_executionContext->contextURL();
+ }
-static String stripURLForUseInReport(Document* document,
- const KURL& url,
- RedirectStatus redirectStatus,
- const String& effectiveDirective) {
- if (!url.isValid())
- return String();
- if (!url.isHierarchical() || url.protocolIs("file"))
- return url.protocol();
-
- // Until we're more careful about the way we deal with navigations in frames
- // (and, by extension, in plugin documents), strip cross-origin 'frame-src'
- // and 'object-src' violations down to an origin. https://crbug.com/633306
- bool canSafelyExposeURL =
- document->getSecurityOrigin()->canRequest(url) ||
- (redirectStatus == RedirectStatus::NoRedirect &&
- !equalIgnoringCase(effectiveDirective,
- ContentSecurityPolicy::FrameSrc) &&
- !equalIgnoringCase(effectiveDirective,
- ContentSecurityPolicy::ObjectSrc));
-
- if (canSafelyExposeURL) {
- // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URLs.
- // It's better for developers if we return the origin of those URLs rather
- // than nothing.
- if (url.protocolIsInHTTPFamily())
- return url.strippedForUseAsReferrer();
- }
- return SecurityOrigin::create(url)->toString();
-}
+ KURL ContentSecurityPolicy::completeURL(const String& url) const {
+ return m_executionContext->contextCompleteURL(url);
+ }
-static void gatherSecurityPolicyViolationEventData(
- SecurityPolicyViolationEventInit& init,
- Document* document,
- const String& directiveText,
- const String& effectiveDirective,
- const KURL& blockedURL,
- const String& header,
- RedirectStatus redirectStatus,
- ContentSecurityPolicy::ViolationType violationType,
- int contextLine) {
- if (equalIgnoringCase(effectiveDirective,
- ContentSecurityPolicy::FrameAncestors)) {
- // If this load was blocked via 'frame-ancestors', then the URL of
- // |document| has not yet been initialized. In this case, we'll set both
- // 'documentURI' and 'blockedURI' to the blocked document's URL.
- init.setDocumentURI(blockedURL.getString());
- init.setBlockedURI(blockedURL.getString());
- } else {
- init.setDocumentURI(document->url().getString());
- switch (violationType) {
- case ContentSecurityPolicy::InlineViolation:
- init.setBlockedURI("inline");
- break;
- case ContentSecurityPolicy::EvalViolation:
- init.setBlockedURI("eval");
- break;
- case ContentSecurityPolicy::URLViolation:
- init.setBlockedURI(stripURLForUseInReport(
- document, blockedURL, redirectStatus, effectiveDirective));
- break;
- }
+ void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) {
+ m_sandboxMask |= mask;
}
- init.setReferrer(document->referrer());
- init.setViolatedDirective(directiveText);
- init.setEffectiveDirective(effectiveDirective);
- init.setOriginalPolicy(header);
- init.setSourceFile(String());
- init.setLineNumber(contextLine);
- init.setColumnNumber(0);
- init.setStatusCode(0);
-
- if (!SecurityOrigin::isSecure(document->url()) && document->loader())
- init.setStatusCode(document->loader()->response().httpStatusCode());
-
- std::unique_ptr<SourceLocation> location = SourceLocation::capture(document);
- if (location->lineNumber()) {
- KURL source = KURL(ParsedURLString, location->url());
- init.setSourceFile(stripURLForUseInReport(document, source, redirectStatus,
- effectiveDirective));
- init.setLineNumber(location->lineNumber());
- init.setColumnNumber(location->columnNumber());
+
+ void ContentSecurityPolicy::treatAsPublicAddress() {
+ if (!RuntimeEnabledFeatures::corsRFC1918Enabled())
+ return;
+ m_treatAsPublicAddress = true;
}
-}
-void ContentSecurityPolicy::reportViolation(
- const String& directiveText,
- const String& effectiveDirective,
- const String& consoleMessage,
- const KURL& blockedURL,
- const Vector<String>& reportEndpoints,
- const String& header,
- ViolationType violationType,
- LocalFrame* contextFrame,
- RedirectStatus redirectStatus,
- int contextLine) {
- ASSERT(violationType == URLViolation || blockedURL.isEmpty());
-
- // TODO(lukasza): Support sending reports from OOPIFs -
- // https://crbug.com/611232 (or move CSP child-src and frame-src checks to the
- // browser process - see https://crbug.com/376522).
- if (!m_executionContext && !contextFrame) {
- DCHECK(equalIgnoringCase(effectiveDirective,
- ContentSecurityPolicy::ChildSrc) ||
- equalIgnoringCase(effectiveDirective,
- ContentSecurityPolicy::FrameSrc) ||
- equalIgnoringCase(effectiveDirective,
- ContentSecurityPolicy::PluginTypes));
- return;
+ void ContentSecurityPolicy::enforceStrictMixedContentChecking() {
+ m_insecureRequestPolicy |= kBlockAllMixedContent;
}
- ASSERT((m_executionContext && !contextFrame) ||
- (equalIgnoringCase(effectiveDirective,
- ContentSecurityPolicy::FrameAncestors) &&
- contextFrame));
+ void ContentSecurityPolicy::upgradeInsecureRequests() {
+ m_insecureRequestPolicy |= kUpgradeInsecureRequests;
+ }
- // FIXME: Support sending reports from worker.
- Document* document =
- contextFrame ? contextFrame->document() : this->document();
- if (!document)
- return;
+ static String stripURLForUseInReport(Document* document,
+ const KURL& url,
+ RedirectStatus redirectStatus,
+ const String& effectiveDirective) {
+ if (!url.isValid())
+ return String();
+ if (!url.isHierarchical() || url.protocolIs("file"))
+ return url.protocol();
+
+ // Until we're more careful about the way we deal with navigations in frames
+ // (and, by extension, in plugin documents), strip cross-origin 'frame-src'
+ // and 'object-src' violations down to an origin. https://crbug.com/633306
+ bool canSafelyExposeURL =
+ document->getSecurityOrigin()->canRequest(url) ||
+ (redirectStatus == RedirectStatus::NoRedirect &&
+ !equalIgnoringCase(effectiveDirective,
+ ContentSecurityPolicy::FrameSrc) &&
+ !equalIgnoringCase(effectiveDirective,
+ ContentSecurityPolicy::ObjectSrc));
+
+ if (canSafelyExposeURL) {
+ // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URLs.
+ // It's better for developers if we return the origin of those URLs rather
+ // than nothing.
+ if (url.protocolIsInHTTPFamily())
+ return url.strippedForUseAsReferrer();
+ }
+ return SecurityOrigin::create(url)->toString();
+ }
- SecurityPolicyViolationEventInit violationData;
- gatherSecurityPolicyViolationEventData(
- violationData, document, directiveText, effectiveDirective, blockedURL,
- header, redirectStatus, violationType, contextLine);
-
- // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded
- // resources should be allowed regardless. We apparently do, however, so
- // we should at least stop spamming reporting endpoints. See
- // https://crbug.com/524356 for detail.
- if (!violationData.sourceFile().isEmpty() &&
- SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
- KURL(ParsedURLString, violationData.sourceFile()).protocol()))
- return;
+ static void gatherSecurityPolicyViolationEventData(
+ SecurityPolicyViolationEventInit& init,
+ Document* document,
+ const String& directiveText,
+ const String& effectiveDirective,
+ const KURL& blockedURL,
+ const String& header,
+ RedirectStatus redirectStatus,
+ ContentSecurityPolicy::ViolationType violationType,
+ int contextLine) {
+ if (equalIgnoringCase(effectiveDirective,
+ ContentSecurityPolicy::FrameAncestors)) {
+ // If this load was blocked via 'frame-ancestors', then the URL of
+ // |document| has not yet been initialized. In this case, we'll set both
+ // 'documentURI' and 'blockedURI' to the blocked document's URL.
+ init.setDocumentURI(blockedURL.getString());
+ init.setBlockedURI(blockedURL.getString());
+ } else {
+ init.setDocumentURI(document->url().getString());
+ switch (violationType) {
+ case ContentSecurityPolicy::InlineViolation:
+ init.setBlockedURI("inline");
+ break;
+ case ContentSecurityPolicy::EvalViolation:
+ init.setBlockedURI("eval");
+ break;
+ case ContentSecurityPolicy::URLViolation:
+ init.setBlockedURI(stripURLForUseInReport(
+ document, blockedURL, redirectStatus, effectiveDirective));
+ break;
+ }
+ }
+ init.setReferrer(document->referrer());
+ init.setViolatedDirective(directiveText);
+ init.setEffectiveDirective(effectiveDirective);
+ init.setOriginalPolicy(header);
+ init.setSourceFile(String());
+ init.setLineNumber(contextLine);
+ init.setColumnNumber(0);
+ init.setStatusCode(0);
+
+ if (!SecurityOrigin::isSecure(document->url()) && document->loader())
+ init.setStatusCode(document->loader()->response().httpStatusCode());
+
+ std::unique_ptr<SourceLocation> location =
+ SourceLocation::capture(document);
+ if (location->lineNumber()) {
+ KURL source = KURL(ParsedURLString, location->url());
+ init.setSourceFile(stripURLForUseInReport(
+ document, source, redirectStatus, effectiveDirective));
+ init.setLineNumber(location->lineNumber());
+ init.setColumnNumber(location->columnNumber());
+ }
+ }
- // We need to be careful here when deciding what information to send to the
- // report-uri. Currently, we send only the current document's URL and the
- // directive that was violated. The document's URL is safe to send because
- // it's the document itself that's requesting that it be sent. You could
- // make an argument that we shouldn't send HTTPS document URLs to HTTP
- // report-uris (for the same reasons that we supress the Referer in that
- // case), but the Referer is sent implicitly whereas this request is only
- // sent explicitly. As for which directive was violated, that's pretty
- // harmless information.
-
- std::unique_ptr<JSONObject> cspReport = JSONObject::create();
- cspReport->setString("document-uri", violationData.documentURI());
- cspReport->setString("referrer", violationData.referrer());
- cspReport->setString("violated-directive", violationData.violatedDirective());
- cspReport->setString("effective-directive",
- violationData.effectiveDirective());
- cspReport->setString("original-policy", violationData.originalPolicy());
- cspReport->setString("blocked-uri", violationData.blockedURI());
- if (violationData.lineNumber())
- cspReport->setInteger("line-number", violationData.lineNumber());
- if (violationData.columnNumber())
- cspReport->setInteger("column-number", violationData.columnNumber());
- if (!violationData.sourceFile().isEmpty())
- cspReport->setString("source-file", violationData.sourceFile());
- cspReport->setInteger("status-code", violationData.statusCode());
-
- std::unique_ptr<JSONObject> reportObject = JSONObject::create();
- reportObject->setObject("csp-report", std::move(cspReport));
- String stringifiedReport = reportObject->toJSONString();
-
- if (!shouldSendViolationReport(stringifiedReport))
- return;
- didSendViolationReport(stringifiedReport);
+ void ContentSecurityPolicy::reportViolation(
+ const String& directiveText,
+ const String& effectiveDirective,
+ const String& consoleMessage,
+ const KURL& blockedURL,
+ const Vector<String>& reportEndpoints,
+ const String& header,
+ ViolationType violationType,
+ LocalFrame* contextFrame,
+ RedirectStatus redirectStatus,
+ int contextLine) {
+ DCHECK(violationType == URLViolation || blockedURL.isEmpty());
+
+ // TODO(lukasza): Support sending reports from OOPIFs -
+ // https://crbug.com/611232 (or move CSP child-src and frame-src checks to
+ // the
+ // browser process - see https://crbug.com/376522).
+ if (!m_executionContext && !contextFrame) {
+ DCHECK(equalIgnoringCase(effectiveDirective,
+ ContentSecurityPolicy::ChildSrc) ||
+ equalIgnoringCase(effectiveDirective,
+ ContentSecurityPolicy::FrameSrc) ||
+ equalIgnoringCase(effectiveDirective,
+ ContentSecurityPolicy::PluginTypes));
+ return;
+ }
- RefPtr<EncodedFormData> report =
- EncodedFormData::create(stringifiedReport.utf8());
+ DCHECK((m_executionContext && !contextFrame) ||
+ (equalIgnoringCase(effectiveDirective,
+ ContentSecurityPolicy::FrameAncestors) &&
+ contextFrame));
+
+ // FIXME: Support sending reports from worker.
+ Document* document =
+ contextFrame ? contextFrame->document() : this->document();
+ if (!document)
+ return;
+
+ SecurityPolicyViolationEventInit violationData;
+ gatherSecurityPolicyViolationEventData(
+ violationData, document, directiveText, effectiveDirective, blockedURL,
+ header, redirectStatus, violationType, contextLine);
+
+ // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded
+ // resources should be allowed regardless. We apparently do, however, so
+ // we should at least stop spamming reporting endpoints. See
+ // https://crbug.com/524356 for detail.
+ if (!violationData.sourceFile().isEmpty() &&
+ SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
+ KURL(ParsedURLString, violationData.sourceFile()).protocol()))
+ return;
+
+ // We need to be careful here when deciding what information to send to the
+ // report-uri. Currently, we send only the current document's URL and the
+ // directive that was violated. The document's URL is safe to send because
+ // it's the document itself that's requesting that it be sent. You could
+ // make an argument that we shouldn't send HTTPS document URLs to HTTP
+ // report-uris (for the same reasons that we supress the Referer in that
+ // case), but the Referer is sent implicitly whereas this request is only
+ // sent explicitly. As for which directive was violated, that's pretty
+ // harmless information.
+
+ std::unique_ptr<JSONObject> cspReport = JSONObject::create();
+ cspReport->setString("document-uri", violationData.documentURI());
+ cspReport->setString("referrer", violationData.referrer());
+ cspReport->setString("violated-directive",
+ violationData.violatedDirective());
+ cspReport->setString("effective-directive",
+ violationData.effectiveDirective());
+ cspReport->setString("original-policy", violationData.originalPolicy());
+ cspReport->setString("blocked-uri", violationData.blockedURI());
+ if (violationData.lineNumber())
+ cspReport->setInteger("line-number", violationData.lineNumber());
+ if (violationData.columnNumber())
+ cspReport->setInteger("column-number", violationData.columnNumber());
+ if (!violationData.sourceFile().isEmpty())
+ cspReport->setString("source-file", violationData.sourceFile());
+ cspReport->setInteger("status-code", violationData.statusCode());
+
+ std::unique_ptr<JSONObject> reportObject = JSONObject::create();
+ reportObject->setObject("csp-report", std::move(cspReport));
+ String stringifiedReport = reportObject->toJSONString();
+
+ if (!shouldSendViolationReport(stringifiedReport))
+ return;
+ didSendViolationReport(stringifiedReport);
+
+ RefPtr<EncodedFormData> report =
+ EncodedFormData::create(stringifiedReport.utf8());
+
+ LocalFrame* frame = document->frame();
+ if (!frame)
+ return;
+ frame->localDOMWindow()->enqueueDocumentEvent(
+ SecurityPolicyViolationEvent::create(
+ EventTypeNames::securitypolicyviolation, violationData));
+
+ for (const String& endpoint : reportEndpoints) {
+ // If we have a context frame we're dealing with 'frame-ancestors' and we
+ // don't have our own execution context. Use the frame's document to
+ // complete the endpoint URL, overriding its URL with the blocked
+ // document's
+ // URL.
+ DCHECK(!contextFrame || !m_executionContext);
+ DCHECK(!contextFrame ||
+ equalIgnoringCase(effectiveDirective, FrameAncestors));
+ KURL url =
+ contextFrame
+ ? frame->document()->completeURLWithOverride(endpoint, blockedURL)
+ : completeURL(endpoint);
+ PingLoader::sendViolationReport(
+ frame, url, report, PingLoader::ContentSecurityPolicyViolationReport);
+ }
+ }
- LocalFrame* frame = document->frame();
- if (!frame)
- return;
- frame->localDOMWindow()->enqueueDocumentEvent(
- SecurityPolicyViolationEvent::create(
- EventTypeNames::securitypolicyviolation, violationData));
-
- for (const String& endpoint : reportEndpoints) {
- // If we have a context frame we're dealing with 'frame-ancestors' and we
- // don't have our own execution context. Use the frame's document to
- // complete the endpoint URL, overriding its URL with the blocked document's
- // URL.
- DCHECK(!contextFrame || !m_executionContext);
- DCHECK(!contextFrame ||
- equalIgnoringCase(effectiveDirective, FrameAncestors));
- KURL url =
- contextFrame
- ? frame->document()->completeURLWithOverride(endpoint, blockedURL)
- : completeURL(endpoint);
- PingLoader::sendViolationReport(
- frame, url, report, PingLoader::ContentSecurityPolicyViolationReport);
+ void ContentSecurityPolicy::reportMixedContent(
+ const KURL& mixedURL,
+ RedirectStatus redirectStatus) {
+ for (const auto& policy : m_policies)
+ policy->reportMixedContent(mixedURL, redirectStatus);
}
-}
-void ContentSecurityPolicy::reportMixedContent(const KURL& mixedURL,
- RedirectStatus redirectStatus) {
- for (const auto& policy : m_policies)
- policy->reportMixedContent(mixedURL, redirectStatus);
-}
+ void ContentSecurityPolicy::reportInvalidReferrer(
+ const String& invalidValue) {
+ logToConsole(
+ "The 'referrer' Content Security Policy directive has the invalid "
+ "value "
+ "\"" +
+ invalidValue +
+ "\". Valid values are \"no-referrer\", \"no-referrer-when-downgrade\", "
+ "\"origin\", \"origin-when-cross-origin\", and \"unsafe-url\".");
+ }
-void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) {
- logToConsole(
- "The 'referrer' Content Security Policy directive has the invalid value "
- "\"" +
- invalidValue +
- "\". Valid values are \"no-referrer\", \"no-referrer-when-downgrade\", "
- "\"origin\", \"origin-when-cross-origin\", and \"unsafe-url\".");
-}
+ void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) {
+ logToConsole(
+ "The report-only Content Security Policy '" + header +
+ "' was delivered via a <meta> element, which is disallowed. The "
+ "policy has been ignored.");
+ }
-void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) {
- logToConsole("The report-only Content Security Policy '" + header +
- "' was delivered via a <meta> element, which is disallowed. The "
- "policy has been ignored.");
-}
+ void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) {
+ logToConsole("The Content Security Policy '" + header +
+ "' was delivered via a <meta> element outside the document's "
+ "<head>, which is disallowed. The policy has been ignored.");
+ }
-void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) {
- logToConsole("The Content Security Policy '" + header +
- "' was delivered via a <meta> element outside the document's "
- "<head>, which is disallowed. The policy has been ignored.");
-}
+ void ContentSecurityPolicy::reportValueForEmptyDirective(
+ const String& name,
+ const String& value) {
+ logToConsole("The Content Security Policy directive '" + name +
+ "' should be empty, but was delivered with a value of '" +
+ value +
+ "'. The directive has been applied, and the value ignored.");
+ }
-void ContentSecurityPolicy::reportValueForEmptyDirective(const String& name,
- const String& value) {
- logToConsole("The Content Security Policy directive '" + name +
- "' should be empty, but was delivered with a value of '" +
- value +
- "'. The directive has been applied, and the value ignored.");
-}
+ void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) {
+ logToConsole("The Content Security Policy directive '" + name +
+ "' is ignored when delivered in a report-only policy.");
+ }
-void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) {
- logToConsole("The Content Security Policy directive '" + name +
- "' is ignored when delivered in a report-only policy.");
-}
+ void ContentSecurityPolicy::reportInvalidDirectiveInMeta(
+ const String& directive) {
+ logToConsole(
+ "Content Security Policies delivered via a <meta> element may not "
+ "contain the " +
+ directive + " directive.");
+ }
-void ContentSecurityPolicy::reportInvalidDirectiveInMeta(
- const String& directive) {
- logToConsole(
- "Content Security Policies delivered via a <meta> element may not "
- "contain the " +
- directive + " directive.");
-}
+ void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) {
+ DEFINE_STATIC_LOCAL(String, allow, ("allow"));
+ DEFINE_STATIC_LOCAL(String, options, ("options"));
+ DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri"));
+ DEFINE_STATIC_LOCAL(String, allowMessage,
+ ("The 'allow' directive has been replaced with "
+ "'default-src'. Please use "
+ "that directive instead, as 'allow' has no effect."));
+ DEFINE_STATIC_LOCAL(
+ String, optionsMessage,
+ ("The 'options' directive has been replaced with 'unsafe-inline' and "
+ "'unsafe-eval' source expressions for the 'script-src' and "
+ "'style-src' "
+ "directives. Please use those directives instead, as 'options' has no "
+ "effect."));
+ DEFINE_STATIC_LOCAL(String, policyURIMessage,
+ ("The 'policy-uri' directive has been removed from the "
+ "specification. Please specify a complete policy via "
+ "the Content-Security-Policy header."));
+
+ String message =
+ "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
+ MessageLevel level = ErrorMessageLevel;
+ if (equalIgnoringCase(name, allow)) {
+ message = allowMessage;
+ } else if (equalIgnoringCase(name, options)) {
+ message = optionsMessage;
+ } else if (equalIgnoringCase(name, policyURI)) {
+ message = policyURIMessage;
+ } else if (isDirectiveName(name)) {
+ message = "The Content-Security-Policy directive '" + name +
+ "' is implemented behind a flag which is currently disabled.\n";
+ level = InfoMessageLevel;
+ }
-void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) {
- DEFINE_STATIC_LOCAL(String, allow, ("allow"));
- DEFINE_STATIC_LOCAL(String, options, ("options"));
- DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri"));
- DEFINE_STATIC_LOCAL(
- String, allowMessage,
- ("The 'allow' directive has been replaced with 'default-src'. Please use "
- "that directive instead, as 'allow' has no effect."));
- DEFINE_STATIC_LOCAL(
- String, optionsMessage,
- ("The 'options' directive has been replaced with 'unsafe-inline' and "
- "'unsafe-eval' source expressions for the 'script-src' and 'style-src' "
- "directives. Please use those directives instead, as 'options' has no "
- "effect."));
- DEFINE_STATIC_LOCAL(String, policyURIMessage,
- ("The 'policy-uri' directive has been removed from the "
- "specification. Please specify a complete policy via "
- "the Content-Security-Policy header."));
-
- String message =
- "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
- MessageLevel level = ErrorMessageLevel;
- if (equalIgnoringCase(name, allow)) {
- message = allowMessage;
- } else if (equalIgnoringCase(name, options)) {
- message = optionsMessage;
- } else if (equalIgnoringCase(name, policyURI)) {
- message = policyURIMessage;
- } else if (isDirectiveName(name)) {
- message = "The Content-Security-Policy directive '" + name +
- "' is implemented behind a flag which is currently disabled.\n";
- level = InfoMessageLevel;
- }
-
- logToConsole(message, level);
-}
+ logToConsole(message, level);
+ }
-void ContentSecurityPolicy::reportDirectiveAsSourceExpression(
- const String& directiveName,
- const String& sourceExpression) {
- String message = "The Content Security Policy directive '" + directiveName +
- "' contains '" + sourceExpression +
- "' as a source expression. Did you mean '" + directiveName +
- " ...; " + sourceExpression + "...' (note the semicolon)?";
- logToConsole(message);
-}
+ void ContentSecurityPolicy::reportDirectiveAsSourceExpression(
+ const String& directiveName,
+ const String& sourceExpression) {
+ String message = "The Content Security Policy directive '" + directiveName +
+ "' contains '" + sourceExpression +
+ "' as a source expression. Did you mean '" +
+ directiveName + " ...; " + sourceExpression +
+ "...' (note the semicolon)?";
+ logToConsole(message);
+ }
-void ContentSecurityPolicy::reportDuplicateDirective(const String& name) {
- String message =
- "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n";
- logToConsole(message);
-}
+ void ContentSecurityPolicy::reportDuplicateDirective(const String& name) {
+ String message = "Ignoring duplicate Content-Security-Policy directive '" +
+ name + "'.\n";
+ logToConsole(message);
+ }
-void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) {
- String message;
- if (pluginType.isNull())
- message =
- "'plugin-types' Content Security Policy directive is empty; all "
- "plugins will be blocked.\n";
- else if (pluginType == "'none'")
- message =
- "Invalid plugin type in 'plugin-types' Content Security Policy "
- "directive: '" +
- pluginType +
- "'. Did you mean to set the object-src directive to 'none'?\n";
- else
- message =
- "Invalid plugin type in 'plugin-types' Content Security Policy "
- "directive: '" +
- pluginType + "'.\n";
- logToConsole(message);
-}
+ void ContentSecurityPolicy::reportInvalidPluginTypes(
+ const String& pluginType) {
+ String message;
+ if (pluginType.isNull()) {
+ message =
+ "'plugin-types' Content Security Policy directive is empty; all "
+ "plugins will be blocked.\n";
+ } else if (pluginType == "'none'") {
+ message =
+ "Invalid plugin type in 'plugin-types' Content Security Policy "
+ "directive: '" +
+ pluginType +
+ "'. Did you mean to set the object-src directive to 'none'?\n";
+ } else {
+ message =
+ "Invalid plugin type in 'plugin-types' Content Security Policy "
+ "directive: '" +
+ pluginType + "'.\n";
+ }
+ logToConsole(message);
+ }
-void ContentSecurityPolicy::reportInvalidSandboxFlags(
- const String& invalidFlags) {
- logToConsole(
- "Error while parsing the 'sandbox' Content Security Policy directive: " +
- invalidFlags);
-}
+ void ContentSecurityPolicy::reportInvalidSandboxFlags(
+ const String& invalidFlags) {
+ logToConsole(
+ "Error while parsing the 'sandbox' Content Security Policy "
+ "directive: " +
+ invalidFlags);
+ }
-void ContentSecurityPolicy::reportInvalidReflectedXSS(
- const String& invalidValue) {
- logToConsole(
- "The 'reflected-xss' Content Security Policy directive has the invalid "
- "value \"" +
- invalidValue +
- "\". Valid values are \"allow\", \"filter\", and \"block\".");
-}
+ void ContentSecurityPolicy::reportInvalidReflectedXSS(
+ const String& invalidValue) {
+ logToConsole(
+ "The 'reflected-xss' Content Security Policy directive has the invalid "
+ "value \"" +
+ invalidValue +
+ "\". Valid values are \"allow\", \"filter\", and \"block\".");
+ }
-void ContentSecurityPolicy::reportInvalidRequireSRIForTokens(
- const String& invalidTokens) {
- logToConsole(
- "Error while parsing the 'require-sri-for' Content Security Policy "
- "directive: " +
- invalidTokens);
-}
+ void ContentSecurityPolicy::reportInvalidRequireSRIForTokens(
+ const String& invalidTokens) {
+ logToConsole(
+ "Error while parsing the 'require-sri-for' Content Security Policy "
+ "directive: " +
+ invalidTokens);
+ }
-void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(
- const String& directiveName,
- const String& value) {
- String message = "The value for Content Security Policy directive '" +
- directiveName + "' contains an invalid character: '" +
- value +
- "'. Non-whitespace characters outside ASCII 0x21-0x7E must "
- "be percent-encoded, as described in RFC 3986, section 2.1: "
- "http://tools.ietf.org/html/rfc3986#section-2.1.";
- logToConsole(message);
-}
+ void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(
+ const String& directiveName,
+ const String& value) {
+ String message =
+ "The value for Content Security Policy directive '" + directiveName +
+ "' contains an invalid character: '" + value +
+ "'. Non-whitespace characters outside ASCII 0x21-0x7E must "
+ "be percent-encoded, as described in RFC 3986, section 2.1: "
+ "http://tools.ietf.org/html/rfc3986#section-2.1.";
+ logToConsole(message);
+ }
-void ContentSecurityPolicy::reportInvalidPathCharacter(
- const String& directiveName,
- const String& value,
- const char invalidChar) {
- ASSERT(invalidChar == '#' || invalidChar == '?');
-
- String ignoring =
- "The fragment identifier, including the '#', will be ignored.";
- if (invalidChar == '?')
- ignoring = "The query component, including the '?', will be ignored.";
- String message = "The source list for Content Security Policy directive '" +
- directiveName +
- "' contains a source with an invalid path: '" + value +
- "'. " + ignoring;
- logToConsole(message);
-}
+ void ContentSecurityPolicy::reportInvalidPathCharacter(
+ const String& directiveName,
+ const String& value,
+ const char invalidChar) {
+ DCHECK(invalidChar == '#' || invalidChar == '?');
+
+ String ignoring =
+ "The fragment identifier, including the '#', will be ignored.";
+ if (invalidChar == '?')
+ ignoring = "The query component, including the '?', will be ignored.";
+ String message = "The source list for Content Security Policy directive '" +
+ directiveName +
+ "' contains a source with an invalid path: '" + value +
+ "'. " + ignoring;
+ logToConsole(message);
+ }
-void ContentSecurityPolicy::reportInvalidSourceExpression(
- const String& directiveName,
- const String& source) {
- String message = "The source list for Content Security Policy directive '" +
- directiveName + "' contains an invalid source: '" + source +
- "'. It will be ignored.";
- if (equalIgnoringCase(source, "'none'"))
- message = message +
- " Note that 'none' has no effect unless it is the only "
- "expression in the source list.";
- logToConsole(message);
-}
+ void ContentSecurityPolicy::reportInvalidSourceExpression(
+ const String& directiveName,
+ const String& source) {
+ String message = "The source list for Content Security Policy directive '" +
+ directiveName + "' contains an invalid source: '" +
+ source + "'. It will be ignored.";
+ if (equalIgnoringCase(source, "'none'")) {
+ message = message +
+ " Note that 'none' has no effect unless it is the only "
+ "expression in the source list.";
+ }
+ logToConsole(message);
+ }
-void ContentSecurityPolicy::reportMissingReportURI(const String& policy) {
- logToConsole("The Content Security Policy '" + policy +
- "' was delivered in report-only mode, but does not specify a "
- "'report-uri'; the policy will have no effect. Please either "
- "add a 'report-uri' directive, or deliver the policy via the "
- "'Content-Security-Policy' header.");
-}
+ void ContentSecurityPolicy::reportMissingReportURI(const String& policy) {
+ logToConsole("The Content Security Policy '" + policy +
+ "' was delivered in report-only mode, but does not specify a "
+ "'report-uri'; the policy will have no effect. Please either "
+ "add a 'report-uri' directive, or deliver the policy via the "
+ "'Content-Security-Policy' header.");
+ }
-void ContentSecurityPolicy::logToConsole(const String& message,
- MessageLevel level) {
- logToConsole(ConsoleMessage::create(SecurityMessageSource, level, message));
-}
+ void ContentSecurityPolicy::logToConsole(const String& message,
+ MessageLevel level) {
+ logToConsole(ConsoleMessage::create(SecurityMessageSource, level, message));
+ }
-void ContentSecurityPolicy::logToConsole(ConsoleMessage* consoleMessage,
- LocalFrame* frame) {
- if (frame)
- frame->document()->addConsoleMessage(consoleMessage);
- else if (m_executionContext)
- m_executionContext->addConsoleMessage(consoleMessage);
- else
- m_consoleMessages.append(consoleMessage);
-}
+ void ContentSecurityPolicy::logToConsole(ConsoleMessage* consoleMessage,
+ LocalFrame* frame) {
+ if (frame)
+ frame->document()->addConsoleMessage(consoleMessage);
+ else if (m_executionContext)
+ m_executionContext->addConsoleMessage(consoleMessage);
+ else
+ m_consoleMessages.append(consoleMessage);
+ }
-void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(
- const String& directiveText) const {
- InspectorInstrumentation::scriptExecutionBlockedByCSP(m_executionContext,
- directiveText);
-}
+ void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(
+ const String& directiveText) const {
+ InspectorInstrumentation::scriptExecutionBlockedByCSP(m_executionContext,
+ directiveText);
+ }
-bool ContentSecurityPolicy::experimentalFeaturesEnabled() const {
- return RuntimeEnabledFeatures::
- experimentalContentSecurityPolicyFeaturesEnabled();
-}
+ bool ContentSecurityPolicy::experimentalFeaturesEnabled() const {
+ return RuntimeEnabledFeatures::
+ experimentalContentSecurityPolicyFeaturesEnabled();
+ }
-bool ContentSecurityPolicy::shouldSendCSPHeader(Resource::Type type) const {
- for (const auto& policy : m_policies) {
- if (policy->shouldSendCSPHeader(type))
- return true;
+ bool ContentSecurityPolicy::shouldSendCSPHeader(Resource::Type type) const {
+ for (const auto& policy : m_policies) {
+ if (policy->shouldSendCSPHeader(type))
+ return true;
+ }
+ return false;
}
- return false;
-}
-bool ContentSecurityPolicy::urlMatchesSelf(const KURL& url) const {
- return m_selfSource->matches(url, RedirectStatus::NoRedirect);
-}
+ bool ContentSecurityPolicy::urlMatchesSelf(const KURL& url) const {
+ return m_selfSource->matches(url, RedirectStatus::NoRedirect);
+ }
-bool ContentSecurityPolicy::protocolMatchesSelf(const KURL& url) const {
- if (equalIgnoringCase("http", m_selfProtocol))
- return url.protocolIsInHTTPFamily();
- return equalIgnoringCase(url.protocol(), m_selfProtocol);
-}
+ bool ContentSecurityPolicy::protocolMatchesSelf(const KURL& url) const {
+ if (equalIgnoringCase("http", m_selfProtocol))
+ return url.protocolIsInHTTPFamily();
+ return equalIgnoringCase(url.protocol(), m_selfProtocol);
+ }
-bool ContentSecurityPolicy::selfMatchesInnerURL() const {
- // Due to backwards-compatibility concerns, we allow 'self' to match blob and
- // filesystem URLs if we're in a context that bypasses Content Security Policy
- // in the main world.
- //
- // TODO(mkwst): Revisit this once embedders have an opportunity to update
- // their extension models.
- return m_executionContext &&
- SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
- m_executionContext->getSecurityOrigin()->protocol());
-}
+ bool ContentSecurityPolicy::selfMatchesInnerURL() const {
+ // Due to backwards-compatibility concerns, we allow 'self' to match blob
+ // and
+ // filesystem URLs if we're in a context that bypasses Content Security
+ // Policy
+ // in the main world.
+ //
+ // TODO(mkwst): Revisit this once embedders have an opportunity to update
+ // their extension models.
+ return m_executionContext &&
+ SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
+ m_executionContext->getSecurityOrigin()->protocol());
+ }
-bool ContentSecurityPolicy::shouldBypassMainWorld(
- const ExecutionContext* context) {
- if (context && context->isDocument()) {
- const Document* document = toDocument(context);
- if (document->frame())
- return document->frame()->script().shouldBypassMainWorldCSP();
+ bool ContentSecurityPolicy::shouldBypassMainWorld(
+ const ExecutionContext* context) {
+ if (context && context->isDocument()) {
+ const Document* document = toDocument(context);
+ if (document->frame())
+ return document->frame()->script().shouldBypassMainWorldCSP();
+ }
+ return false;
}
- return false;
-}
-bool ContentSecurityPolicy::shouldSendViolationReport(
- const String& report) const {
- // Collisions have no security impact, so we can save space by storing only
- // the string's hash rather than the whole report.
- return !m_violationReportsSent.contains(report.impl()->hash());
-}
+ bool ContentSecurityPolicy::shouldSendViolationReport(
+ const String& report) const {
+ // Collisions have no security impact, so we can save space by storing only
+ // the string's hash rather than the whole report.
+ return !m_violationReportsSent.contains(report.impl()->hash());
+ }
-void ContentSecurityPolicy::didSendViolationReport(const String& report) {
- m_violationReportsSent.add(report.impl()->hash());
-}
+ void ContentSecurityPolicy::didSendViolationReport(const String& report) {
+ m_violationReportsSent.add(report.impl()->hash());
+ }
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698