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

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

Issue 2784753003: CSP: Enable whitelisting of external JavaScript via hashes (Closed)
Patch Set: remove duplicate test Created 3 years, 8 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/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 6a1e4bc6a5671ce07de0bd72fa94dbdd849d17f4..cc8bd7826d5e4c71a6a0fe922795e6532205e999 100644
--- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -45,6 +45,36 @@ inline bool isASCIIAlphanumericOrHyphen(CharType c) {
return isASCIIAlphanumeric(c) || c == '-';
}
+ContentSecurityPolicyHashAlgorithm convertHashAlgorithmToCSPHashAlgorithm(
+ HashAlgorithm algorithm) {
+ switch (algorithm) {
+ case HashAlgorithmSha1:
+ // Sha1 is not supported.
+ return ContentSecurityPolicyHashAlgorithmNone;
+ case HashAlgorithmSha256:
+ return ContentSecurityPolicyHashAlgorithmSha256;
+ case HashAlgorithmSha384:
+ return ContentSecurityPolicyHashAlgorithmSha384;
+ case HashAlgorithmSha512:
+ return ContentSecurityPolicyHashAlgorithmSha512;
+ }
+ NOTREACHED();
+ return ContentSecurityPolicyHashAlgorithmNone;
+}
+
+// IntegrityMetadata (from SRI) has base64-encoded digest values, but CSP uses
+// binary format. This converts from the former to the latter.
+bool parseBase64Digest(String base64, DigestValue& hash) {
+ 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,
@@ -178,6 +208,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;
+ // 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);
@@ -633,20 +681,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(

Powered by Google App Engine
This is Rietveld 408576698