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( |