Chromium Code Reviews| Index: third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp |
| diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp |
| index 86366e38881fe4d67fa7d5c2b5c81c069e65ecf0..a3933984525f9fb548388346aa634e416d14b997 100644 |
| --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp |
| +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp |
| @@ -45,6 +45,33 @@ inline bool isASCIIAlphanumericOrHyphen(CharType c) { |
| return isASCIIAlphanumeric(c) || c == '-'; |
| } |
| +ContentSecurityPolicyHashAlgorithm convertHashAlgorithmToCSPHashAlgorithm( |
|
Mike West
2017/03/29 13:03:54
Hrm. Can we just make these the same thing? I don'
Marc Treib
2017/03/30 09:48:51
I was wondering that myself :)
The CSP variant has
|
| + HashAlgorithm algorithm) { |
| + switch (algorithm) { |
| + case HashAlgorithmSha1: |
| + return ContentSecurityPolicyHashAlgorithmSha1; |
|
Mike West
2017/03/29 13:03:54
We shouldn't support SHA-1.
Marc Treib
2017/03/30 09:48:51
Done.
|
| + case HashAlgorithmSha256: |
| + return ContentSecurityPolicyHashAlgorithmSha256; |
| + case HashAlgorithmSha384: |
| + return ContentSecurityPolicyHashAlgorithmSha384; |
| + case HashAlgorithmSha512: |
| + return ContentSecurityPolicyHashAlgorithmSha512; |
| + } |
| + NOTREACHED(); |
| + return ContentSecurityPolicyHashAlgorithmNone; |
| +} |
| + |
| +bool parseBase64Digest(String base64, DigestValue& hash) { |
|
Mike West
2017/03/29 13:03:54
Can you add some comments noting why this is neces
Marc Treib
2017/03/30 09:48:51
The DigestValue type has a binary digest value, wh
|
| + Vector<char> hashVector; |
| + // We accept base64url-encoded data here by normalizing it to base64. |
| + if (!base64Decode(normalizeToBase64(base64), hashVector)) |
| + return false; |
| + if (hashVector.isEmpty() || hashVector.size() > kMaxDigestSize) |
| + return false; |
| + hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size()); |
| + return true; |
| +} |
| + |
| } // namespace |
| CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, |
| @@ -171,6 +198,24 @@ bool CSPDirectiveList::isMatchingNoncePresent(SourceListDirective* directive, |
| return directive && directive->allowNonce(nonce); |
| } |
| +bool CSPDirectiveList::areAllMatchingHashesPresent( |
| + SourceListDirective* directive, |
| + const IntegrityMetadataSet& hashes) const { |
| + if (!directive || hashes.isEmpty()) |
| + return false; |
| + for (const std::pair<WTF::String, HashAlgorithm>& hash : hashes) { |
| + // Convert the hash from integrity metadata format to CSP format. |
| + CSPHashValue cspHash; |
| + cspHash.first = convertHashAlgorithmToCSPHashAlgorithm(hash.second); |
| + if (!parseBase64Digest(hash.first, cspHash.second)) |
| + return false; |
|
Mike West
2017/03/29 13:03:54
This appears to replicate much of the logic in `ch
Marc Treib
2017/03/30 09:48:51
I don't think they're all that similar. checkDiges
|
| + // All integrity hashes must be listed in the CSP. |
| + if (!directive->allowHash(cspHash)) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| bool CSPDirectiveList::checkHash(SourceListDirective* directive, |
| const CSPHashValue& hashValue) const { |
| return !directive || directive->allowHash(hashValue); |
| @@ -624,20 +669,23 @@ bool CSPDirectiveList::allowPluginType( |
| bool CSPDirectiveList::allowScriptFromSource( |
| const KURL& url, |
| const String& nonce, |
| + const IntegrityMetadataSet& hashes, |
| ParserDisposition parserDisposition, |
| ResourceRequest::RedirectStatus redirectStatus, |
| SecurityViolationReportingPolicy reportingPolicy) const { |
| - if (isMatchingNoncePresent(operativeDirective(m_scriptSrc.get()), nonce)) |
| + SourceListDirective* directive = operativeDirective(m_scriptSrc.get()); |
| + if (isMatchingNoncePresent(directive, nonce)) |
| return true; |
| if (parserDisposition == NotParserInserted && allowDynamic()) |
| return true; |
| + if (areAllMatchingHashesPresent(directive, hashes)) |
| + return true; |
| return reportingPolicy == SecurityViolationReportingPolicy::Report |
| ? checkSourceAndReportViolation( |
| - operativeDirective(m_scriptSrc.get()), url, |
| + directive, url, |
| ContentSecurityPolicy::DirectiveType::ScriptSrc, |
| redirectStatus) |
| - : checkSource(operativeDirective(m_scriptSrc.get()), url, |
| - redirectStatus); |
| + : checkSource(directive, url, redirectStatus); |
| } |
| bool CSPDirectiveList::allowObjectFromSource( |