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

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

Issue 2449873004: Removing CSPSourceList level up to SourceListDirective. (Closed)
Patch Set: Exporting CSPDirective 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/CSPSourceList.cpp
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp
deleted file mode 100644
index e429ce978f078e86ac6b5b18795deca5988e7892..0000000000000000000000000000000000000000
--- a/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp
+++ /dev/null
@@ -1,565 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/frame/csp/CSPSourceList.h"
-
-#include "core/frame/csp/CSPSource.h"
-#include "core/frame/csp/ContentSecurityPolicy.h"
-#include "platform/weborigin/KURL.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "wtf/HashSet.h"
-#include "wtf/text/Base64.h"
-#include "wtf/text/ParsingUtilities.h"
-#include "wtf/text/StringToNumber.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-
-static bool isSourceListNone(const UChar* begin, const UChar* end) {
- skipWhile<UChar, isASCIISpace>(begin, end);
-
- const UChar* position = begin;
- skipWhile<UChar, isSourceCharacter>(position, end);
- if (!equalIgnoringCase("'none'", StringView(begin, position - begin)))
- return false;
-
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position != end)
- return false;
-
- return true;
-}
-
-CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy,
- const String& directiveName)
- : m_policy(policy),
- m_directiveName(directiveName),
- m_allowSelf(false),
- m_allowStar(false),
- m_allowInline(false),
- m_allowEval(false),
- m_allowDynamic(false),
- m_allowHashedAttributes(false),
- m_hashAlgorithmsUsed(0) {}
-
-bool CSPSourceList::matches(
- const KURL& url,
- ResourceRequest::RedirectStatus redirectStatus) const {
- // Wildcards match network schemes ('http', 'https', 'ftp', 'ws', 'wss'), and
- // the scheme of the protected resource:
- // https://w3c.github.io/webappsec-csp/#match-url-to-source-expression. Other
- // schemes, including custom schemes, must be explicitly listed in a source
- // list.
- if (m_allowStar) {
- if (url.protocolIsInHTTPFamily() || url.protocolIs("ftp") ||
- url.protocolIs("ws") || url.protocolIs("wss") ||
- m_policy->protocolMatchesSelf(url))
- return true;
-
- return hasSourceMatchInList(url, redirectStatus);
- }
-
- KURL effectiveURL =
- m_policy->selfMatchesInnerURL() && SecurityOrigin::shouldUseInnerURL(url)
- ? SecurityOrigin::extractInnerURL(url)
- : url;
-
- if (m_allowSelf && m_policy->urlMatchesSelf(effectiveURL))
- return true;
-
- return hasSourceMatchInList(effectiveURL, redirectStatus);
-}
-
-bool CSPSourceList::allowInline() const {
- return m_allowInline;
-}
-
-bool CSPSourceList::allowEval() const {
- return m_allowEval;
-}
-
-bool CSPSourceList::allowDynamic() const {
- return m_allowDynamic;
-}
-
-bool CSPSourceList::allowNonce(const String& nonce) const {
- return !nonce.isNull() && m_nonces.contains(nonce);
-}
-
-bool CSPSourceList::allowHash(const CSPHashValue& hashValue) const {
- return m_hashes.contains(hashValue);
-}
-
-bool CSPSourceList::allowHashedAttributes() const {
- return m_allowHashedAttributes;
-}
-
-uint8_t CSPSourceList::hashAlgorithmsUsed() const {
- return m_hashAlgorithmsUsed;
-}
-
-bool CSPSourceList::isHashOrNoncePresent() const {
- return !m_nonces.isEmpty() ||
- m_hashAlgorithmsUsed != ContentSecurityPolicyHashAlgorithmNone;
-}
-
-// source-list = *WSP [ source *( 1*WSP source ) *WSP ]
-// / *WSP "'none'" *WSP
-//
-void CSPSourceList::parse(const UChar* begin, const UChar* end) {
- // We represent 'none' as an empty m_list.
- if (isSourceListNone(begin, end))
- return;
-
- const UChar* position = begin;
- while (position < end) {
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end)
- return;
-
- const UChar* beginSource = position;
- skipWhile<UChar, isSourceCharacter>(position, end);
-
- String scheme, host, path;
- int port = 0;
- CSPSource::WildcardDisposition hostWildcard = CSPSource::NoWildcard;
- CSPSource::WildcardDisposition portWildcard = CSPSource::NoWildcard;
-
- if (parseSource(beginSource, position, scheme, host, port, path,
- hostWildcard, portWildcard)) {
- // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
- // etc.) aren't stored in m_list, but as attributes on the source
- // list itself.
- if (scheme.isEmpty() && host.isEmpty())
- continue;
- if (m_policy->isDirectiveName(host))
- m_policy->reportDirectiveAsSourceExpression(m_directiveName, host);
- m_list.append(new CSPSource(m_policy, scheme, host, port, path,
- hostWildcard, portWildcard));
- } else {
- m_policy->reportInvalidSourceExpression(
- m_directiveName, String(beginSource, position - beginSource));
- }
-
- ASSERT(position == end || isASCIISpace(*position));
- }
-}
-
-// source = scheme ":"
-// / ( [ scheme "://" ] host [ port ] [ path ] )
-// / "'self'"
-bool CSPSourceList::parseSource(const UChar* begin,
- const UChar* end,
- String& scheme,
- String& host,
- int& port,
- String& path,
- CSPSource::WildcardDisposition& hostWildcard,
- CSPSource::WildcardDisposition& portWildcard) {
- if (begin == end)
- return false;
-
- StringView token(begin, end - begin);
-
- if (equalIgnoringCase("'none'", token))
- return false;
-
- if (end - begin == 1 && *begin == '*') {
- addSourceStar();
- return true;
- }
-
- if (equalIgnoringCase("'self'", token)) {
- addSourceSelf();
- return true;
- }
-
- if (equalIgnoringCase("'unsafe-inline'", token)) {
- addSourceUnsafeInline();
- return true;
- }
-
- if (equalIgnoringCase("'unsafe-eval'", token)) {
- addSourceUnsafeEval();
- return true;
- }
-
- if (equalIgnoringCase("'strict-dynamic'", token)) {
- addSourceStrictDynamic();
- return true;
- }
-
- if (equalIgnoringCase("'unsafe-hashed-attributes'", token)) {
- addSourceUnsafeHashedAttributes();
- return true;
- }
-
- String nonce;
- if (!parseNonce(begin, end, nonce))
- return false;
-
- if (!nonce.isNull()) {
- addSourceNonce(nonce);
- return true;
- }
-
- DigestValue hash;
- ContentSecurityPolicyHashAlgorithm algorithm =
- ContentSecurityPolicyHashAlgorithmNone;
- if (!parseHash(begin, end, hash, algorithm))
- return false;
-
- if (hash.size() > 0) {
- addSourceHash(algorithm, hash);
- return true;
- }
-
- const UChar* position = begin;
- const UChar* beginHost = begin;
- const UChar* beginPath = end;
- const UChar* beginPort = 0;
-
- skipWhile<UChar, isNotColonOrSlash>(position, end);
-
- if (position == end) {
- // host
- // ^
- return parseHost(beginHost, position, host, hostWildcard);
- }
-
- if (position < end && *position == '/') {
- // host/path || host/ || /
- // ^ ^ ^
- return parseHost(beginHost, position, host, hostWildcard) &&
- parsePath(position, end, path);
- }
-
- if (position < end && *position == ':') {
- if (end - position == 1) {
- // scheme:
- // ^
- return parseScheme(begin, position, scheme);
- }
-
- if (position[1] == '/') {
- // scheme://host || scheme://
- // ^ ^
- if (!parseScheme(begin, position, scheme) ||
- !skipExactly<UChar>(position, end, ':') ||
- !skipExactly<UChar>(position, end, '/') ||
- !skipExactly<UChar>(position, end, '/'))
- return false;
- if (position == end)
- return false;
- beginHost = position;
- skipWhile<UChar, isNotColonOrSlash>(position, end);
- }
-
- if (position < end && *position == ':') {
- // host:port || scheme://host:port
- // ^ ^
- beginPort = position;
- skipUntil<UChar>(position, end, '/');
- }
- }
-
- if (position < end && *position == '/') {
- // scheme://host/path || scheme://host:port/path
- // ^ ^
- if (position == beginHost)
- return false;
- beginPath = position;
- }
-
- if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host,
- hostWildcard))
- return false;
-
- if (beginPort) {
- if (!parsePort(beginPort, beginPath, port, portWildcard))
- return false;
- } else {
- port = 0;
- }
-
- if (beginPath != end) {
- if (!parsePath(beginPath, end, path))
- return false;
- }
-
- return true;
-}
-
-// nonce-source = "'nonce-" nonce-value "'"
-// nonce-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
-//
-bool CSPSourceList::parseNonce(const UChar* begin,
- const UChar* end,
- String& nonce) {
- size_t nonceLength = end - begin;
- StringView prefix("'nonce-");
-
- // TODO(esprehn): Should be StringView(begin, nonceLength).startsWith(prefix).
- if (nonceLength <= prefix.length() ||
- !equalIgnoringCase(prefix, StringView(begin, prefix.length())))
- return true;
-
- const UChar* position = begin + prefix.length();
- const UChar* nonceBegin = position;
-
- ASSERT(position < end);
- skipWhile<UChar, isNonceCharacter>(position, end);
- ASSERT(nonceBegin <= position);
-
- if (position + 1 != end || *position != '\'' || position == nonceBegin)
- return false;
-
- nonce = String(nonceBegin, position - nonceBegin);
- return true;
-}
-
-// hash-source = "'" hash-algorithm "-" hash-value "'"
-// hash-algorithm = "sha1" / "sha256" / "sha384" / "sha512"
-// hash-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
-//
-bool CSPSourceList::parseHash(
- const UChar* begin,
- const UChar* end,
- DigestValue& hash,
- ContentSecurityPolicyHashAlgorithm& hashAlgorithm) {
- // Any additions or subtractions from this struct should also modify the
- // respective entries in the kAlgorithmMap array in checkDigest().
- static const struct {
- const char* prefix;
- ContentSecurityPolicyHashAlgorithm type;
- } kSupportedPrefixes[] = {
- // FIXME: Drop support for SHA-1. It's not in the spec.
- {"'sha1-", ContentSecurityPolicyHashAlgorithmSha1},
- {"'sha256-", ContentSecurityPolicyHashAlgorithmSha256},
- {"'sha384-", ContentSecurityPolicyHashAlgorithmSha384},
- {"'sha512-", ContentSecurityPolicyHashAlgorithmSha512},
- {"'sha-256-", ContentSecurityPolicyHashAlgorithmSha256},
- {"'sha-384-", ContentSecurityPolicyHashAlgorithmSha384},
- {"'sha-512-", ContentSecurityPolicyHashAlgorithmSha512}};
-
- StringView prefix;
- hashAlgorithm = ContentSecurityPolicyHashAlgorithmNone;
- size_t hashLength = end - begin;
-
- for (const auto& algorithm : kSupportedPrefixes) {
- prefix = algorithm.prefix;
- // TODO(esprehn): Should be StringView(begin, end -
- // begin).startsWith(prefix).
- if (hashLength > prefix.length() &&
- equalIgnoringCase(prefix, StringView(begin, prefix.length()))) {
- hashAlgorithm = algorithm.type;
- break;
- }
- }
-
- if (hashAlgorithm == ContentSecurityPolicyHashAlgorithmNone)
- return true;
-
- const UChar* position = begin + prefix.length();
- const UChar* hashBegin = position;
-
- ASSERT(position < end);
- skipWhile<UChar, isBase64EncodedCharacter>(position, end);
- ASSERT(hashBegin <= position);
-
- // Base64 encodings may end with exactly one or two '=' characters
- if (position < end)
- skipExactly<UChar>(position, position + 1, '=');
- if (position < end)
- skipExactly<UChar>(position, position + 1, '=');
-
- if (position + 1 != end || *position != '\'' || position == hashBegin)
- return false;
-
- Vector<char> hashVector;
- // We accept base64url-encoded data here by normalizing it to base64.
- base64Decode(normalizeToBase64(String(hashBegin, position - hashBegin)),
- hashVector);
- if (hashVector.size() > kMaxDigestSize)
- return false;
- hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size());
- return true;
-}
-
-// ; <scheme> production from RFC 3986
-// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-//
-bool CSPSourceList::parseScheme(const UChar* begin,
- const UChar* end,
- String& scheme) {
- ASSERT(begin <= end);
- ASSERT(scheme.isEmpty());
-
- if (begin == end)
- return false;
-
- const UChar* position = begin;
-
- if (!skipExactly<UChar, isASCIIAlpha>(position, end))
- return false;
-
- skipWhile<UChar, isSchemeContinuationCharacter>(position, end);
-
- if (position != end)
- return false;
-
- scheme = String(begin, end - begin);
- return true;
-}
-
-// host = [ "*." ] 1*host-char *( "." 1*host-char )
-// / "*"
-// host-char = ALPHA / DIGIT / "-"
-//
-bool CSPSourceList::parseHost(const UChar* begin,
- const UChar* end,
- String& host,
- CSPSource::WildcardDisposition& hostWildcard) {
- ASSERT(begin <= end);
- ASSERT(host.isEmpty());
- ASSERT(hostWildcard == CSPSource::NoWildcard);
-
- if (begin == end)
- return false;
-
- const UChar* position = begin;
-
- if (skipExactly<UChar>(position, end, '*')) {
- hostWildcard = CSPSource::HasWildcard;
-
- if (position == end)
- return true;
-
- if (!skipExactly<UChar>(position, end, '.'))
- return false;
- }
-
- const UChar* hostBegin = position;
-
- while (position < end) {
- if (!skipExactly<UChar, isHostCharacter>(position, end))
- return false;
-
- skipWhile<UChar, isHostCharacter>(position, end);
-
- if (position < end && !skipExactly<UChar>(position, end, '.'))
- return false;
- }
-
- ASSERT(position == end);
- host = String(hostBegin, end - hostBegin);
- return true;
-}
-
-bool CSPSourceList::parsePath(const UChar* begin,
- const UChar* end,
- String& path) {
- ASSERT(begin <= end);
- ASSERT(path.isEmpty());
-
- const UChar* position = begin;
- skipWhile<UChar, isPathComponentCharacter>(position, end);
- // path/to/file.js?query=string || path/to/file.js#anchor
- // ^ ^
- if (position < end)
- m_policy->reportInvalidPathCharacter(m_directiveName,
- String(begin, end - begin), *position);
-
- path = decodeURLEscapeSequences(String(begin, position - begin));
-
- ASSERT(position <= end);
- ASSERT(position == end || (*position == '#' || *position == '?'));
- return true;
-}
-
-// port = ":" ( 1*DIGIT / "*" )
-//
-bool CSPSourceList::parsePort(const UChar* begin,
- const UChar* end,
- int& port,
- CSPSource::WildcardDisposition& portWildcard) {
- ASSERT(begin <= end);
- ASSERT(!port);
- ASSERT(portWildcard == CSPSource::NoWildcard);
-
- if (!skipExactly<UChar>(begin, end, ':'))
- ASSERT_NOT_REACHED();
-
- if (begin == end)
- return false;
-
- if (end - begin == 1 && *begin == '*') {
- port = 0;
- portWildcard = CSPSource::HasWildcard;
- return true;
- }
-
- const UChar* position = begin;
- skipWhile<UChar, isASCIIDigit>(position, end);
-
- if (position != end)
- return false;
-
- bool ok;
- port = charactersToIntStrict(begin, end - begin, &ok);
- return ok;
-}
-
-void CSPSourceList::addSourceSelf() {
- m_allowSelf = true;
-}
-
-void CSPSourceList::addSourceStar() {
- m_allowStar = true;
-}
-
-void CSPSourceList::addSourceUnsafeInline() {
- m_allowInline = true;
-}
-
-void CSPSourceList::addSourceUnsafeEval() {
- m_allowEval = true;
-}
-
-void CSPSourceList::addSourceStrictDynamic() {
- m_allowDynamic = true;
-}
-
-void CSPSourceList::addSourceUnsafeHashedAttributes() {
- m_allowHashedAttributes = true;
-}
-
-void CSPSourceList::addSourceNonce(const String& nonce) {
- m_nonces.add(nonce);
-}
-
-void CSPSourceList::addSourceHash(
- const ContentSecurityPolicyHashAlgorithm& algorithm,
- const DigestValue& hash) {
- m_hashes.add(CSPHashValue(algorithm, hash));
- m_hashAlgorithmsUsed |= algorithm;
-}
-
-bool CSPSourceList::hasSourceMatchInList(
- const KURL& url,
- ResourceRequest::RedirectStatus redirectStatus) const {
- for (size_t i = 0; i < m_list.size(); ++i) {
- if (m_list[i]->matches(url, redirectStatus))
- return true;
- }
-
- return false;
-}
-
-DEFINE_TRACE(CSPSourceList) {
- visitor->trace(m_policy);
- visitor->trace(m_list);
-}
-
-} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698