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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/csp/CSPDirectiveList.h" 5 #include "core/frame/csp/CSPDirectiveList.h"
6 6
7 #include "bindings/core/v8/SourceLocation.h" 7 #include "bindings/core/v8/SourceLocation.h"
8 #include "core/dom/Document.h" 8 #include "core/dom/Document.h"
9 #include "core/dom/SecurityContext.h" 9 #include "core/dom/SecurityContext.h"
10 #include "core/dom/SpaceSplitString.h" 10 #include "core/dom/SpaceSplitString.h"
(...skipping 27 matching lines...) Expand all
38 38
39 return "sha256-" + base64Encode(reinterpret_cast<char*>(digest.data()), 39 return "sha256-" + base64Encode(reinterpret_cast<char*>(digest.data()),
40 digest.size(), Base64DoNotInsertLFs); 40 digest.size(), Base64DoNotInsertLFs);
41 } 41 }
42 42
43 template <typename CharType> 43 template <typename CharType>
44 inline bool isASCIIAlphanumericOrHyphen(CharType c) { 44 inline bool isASCIIAlphanumericOrHyphen(CharType c) {
45 return isASCIIAlphanumeric(c) || c == '-'; 45 return isASCIIAlphanumeric(c) || c == '-';
46 } 46 }
47 47
48 ContentSecurityPolicyHashAlgorithm convertHashAlgorithmToCSPHashAlgorithm(
49 HashAlgorithm algorithm) {
50 switch (algorithm) {
51 case HashAlgorithmSha1:
52 // Sha1 is not supported.
53 return ContentSecurityPolicyHashAlgorithmNone;
54 case HashAlgorithmSha256:
55 return ContentSecurityPolicyHashAlgorithmSha256;
56 case HashAlgorithmSha384:
57 return ContentSecurityPolicyHashAlgorithmSha384;
58 case HashAlgorithmSha512:
59 return ContentSecurityPolicyHashAlgorithmSha512;
60 }
61 NOTREACHED();
62 return ContentSecurityPolicyHashAlgorithmNone;
63 }
64
65 // IntegrityMetadata (from SRI) has base64-encoded digest values, but CSP uses
66 // binary format. This converts from the former to the latter.
67 bool parseBase64Digest(String base64, DigestValue& hash) {
68 Vector<char> hashVector;
69 // We accept base64url-encoded data here by normalizing it to base64.
70 if (!base64Decode(normalizeToBase64(base64), hashVector))
71 return false;
72 if (hashVector.isEmpty() || hashVector.size() > kMaxDigestSize)
73 return false;
74 hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size());
75 return true;
76 }
77
48 } // namespace 78 } // namespace
49 79
50 CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, 80 CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy,
51 ContentSecurityPolicyHeaderType type, 81 ContentSecurityPolicyHeaderType type,
52 ContentSecurityPolicyHeaderSource source) 82 ContentSecurityPolicyHeaderSource source)
53 : m_policy(policy), 83 : m_policy(policy),
54 m_headerType(type), 84 m_headerType(type),
55 m_headerSource(source), 85 m_headerSource(source),
56 m_hasSandboxPolicy(false), 86 m_hasSandboxPolicy(false),
57 m_strictMixedContentCheckingEnforced(false), 87 m_strictMixedContentCheckingEnforced(false),
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 201
172 bool CSPDirectiveList::checkEval(SourceListDirective* directive) const { 202 bool CSPDirectiveList::checkEval(SourceListDirective* directive) const {
173 return !directive || directive->allowEval(); 203 return !directive || directive->allowEval();
174 } 204 }
175 205
176 bool CSPDirectiveList::isMatchingNoncePresent(SourceListDirective* directive, 206 bool CSPDirectiveList::isMatchingNoncePresent(SourceListDirective* directive,
177 const String& nonce) const { 207 const String& nonce) const {
178 return directive && directive->allowNonce(nonce); 208 return directive && directive->allowNonce(nonce);
179 } 209 }
180 210
211 bool CSPDirectiveList::areAllMatchingHashesPresent(
212 SourceListDirective* directive,
213 const IntegrityMetadataSet& hashes) const {
214 if (!directive || hashes.isEmpty())
215 return false;
216 for (const std::pair<WTF::String, HashAlgorithm>& hash : hashes) {
217 // Convert the hash from integrity metadata format to CSP format.
218 CSPHashValue cspHash;
219 cspHash.first = convertHashAlgorithmToCSPHashAlgorithm(hash.second);
220 if (!parseBase64Digest(hash.first, cspHash.second))
221 return false;
222 // All integrity hashes must be listed in the CSP.
223 if (!directive->allowHash(cspHash))
224 return false;
225 }
226 return true;
227 }
228
181 bool CSPDirectiveList::checkHash(SourceListDirective* directive, 229 bool CSPDirectiveList::checkHash(SourceListDirective* directive,
182 const CSPHashValue& hashValue) const { 230 const CSPHashValue& hashValue) const {
183 return !directive || directive->allowHash(hashValue); 231 return !directive || directive->allowHash(hashValue);
184 } 232 }
185 233
186 bool CSPDirectiveList::checkHashedAttributes( 234 bool CSPDirectiveList::checkHashedAttributes(
187 SourceListDirective* directive) const { 235 SourceListDirective* directive) const {
188 return !directive || directive->allowHashedAttributes(); 236 return !directive || directive->allowHashedAttributes();
189 } 237 }
190 238
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 "Refused to load '" + url.elidedString() + "' (MIME type '" + 674 "Refused to load '" + url.elidedString() + "' (MIME type '" +
627 typeAttribute + 675 typeAttribute +
628 "') because it violates the following Content Security " 676 "') because it violates the following Content Security "
629 "Policy Directive: ") 677 "Policy Directive: ")
630 : checkMediaType(m_pluginTypes.get(), type, typeAttribute); 678 : checkMediaType(m_pluginTypes.get(), type, typeAttribute);
631 } 679 }
632 680
633 bool CSPDirectiveList::allowScriptFromSource( 681 bool CSPDirectiveList::allowScriptFromSource(
634 const KURL& url, 682 const KURL& url,
635 const String& nonce, 683 const String& nonce,
684 const IntegrityMetadataSet& hashes,
636 ParserDisposition parserDisposition, 685 ParserDisposition parserDisposition,
637 ResourceRequest::RedirectStatus redirectStatus, 686 ResourceRequest::RedirectStatus redirectStatus,
638 SecurityViolationReportingPolicy reportingPolicy) const { 687 SecurityViolationReportingPolicy reportingPolicy) const {
639 if (isMatchingNoncePresent(operativeDirective(m_scriptSrc.get()), nonce)) 688 SourceListDirective* directive = operativeDirective(m_scriptSrc.get());
689 if (isMatchingNoncePresent(directive, nonce))
640 return true; 690 return true;
641 if (parserDisposition == NotParserInserted && allowDynamic()) 691 if (parserDisposition == NotParserInserted && allowDynamic())
642 return true; 692 return true;
693 if (areAllMatchingHashesPresent(directive, hashes))
694 return true;
643 return reportingPolicy == SecurityViolationReportingPolicy::Report 695 return reportingPolicy == SecurityViolationReportingPolicy::Report
644 ? checkSourceAndReportViolation( 696 ? checkSourceAndReportViolation(
645 operativeDirective(m_scriptSrc.get()), url, 697 directive, url,
646 ContentSecurityPolicy::DirectiveType::ScriptSrc, 698 ContentSecurityPolicy::DirectiveType::ScriptSrc,
647 redirectStatus) 699 redirectStatus)
648 : checkSource(operativeDirective(m_scriptSrc.get()), url, 700 : checkSource(directive, url, redirectStatus);
649 redirectStatus);
650 } 701 }
651 702
652 bool CSPDirectiveList::allowObjectFromSource( 703 bool CSPDirectiveList::allowObjectFromSource(
653 const KURL& url, 704 const KURL& url,
654 ResourceRequest::RedirectStatus redirectStatus, 705 ResourceRequest::RedirectStatus redirectStatus,
655 SecurityViolationReportingPolicy reportingPolicy) const { 706 SecurityViolationReportingPolicy reportingPolicy) const {
656 if (url.protocolIsAbout()) 707 if (url.protocolIsAbout())
657 return true; 708 return true;
658 return reportingPolicy == SecurityViolationReportingPolicy::Report 709 return reportingPolicy == SecurityViolationReportingPolicy::Report
659 ? checkSourceAndReportViolation( 710 ? checkSourceAndReportViolation(
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 visitor->trace(m_imgSrc); 1414 visitor->trace(m_imgSrc);
1364 visitor->trace(m_mediaSrc); 1415 visitor->trace(m_mediaSrc);
1365 visitor->trace(m_manifestSrc); 1416 visitor->trace(m_manifestSrc);
1366 visitor->trace(m_objectSrc); 1417 visitor->trace(m_objectSrc);
1367 visitor->trace(m_scriptSrc); 1418 visitor->trace(m_scriptSrc);
1368 visitor->trace(m_styleSrc); 1419 visitor->trace(m_styleSrc);
1369 visitor->trace(m_workerSrc); 1420 visitor->trace(m_workerSrc);
1370 } 1421 }
1371 1422
1372 } // namespace blink 1423 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698