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

Side by Side Diff: Source/core/frame/ContentSecurityPolicy.cpp

Issue 26481005: Implementation of script hashes for CSP. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added tests Created 7 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google, Inc. All rights reserved. 2 * Copyright (C) 2011 Google, Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "core/page/UseCounter.h" 42 #include "core/page/UseCounter.h"
43 #include "core/platform/ParsingUtilities.h" 43 #include "core/platform/ParsingUtilities.h"
44 #include "core/platform/network/FormData.h" 44 #include "core/platform/network/FormData.h"
45 #include "core/platform/network/ResourceResponse.h" 45 #include "core/platform/network/ResourceResponse.h"
46 #include "platform/JSONValues.h" 46 #include "platform/JSONValues.h"
47 #include "weborigin/KURL.h" 47 #include "weborigin/KURL.h"
48 #include "weborigin/KnownPorts.h" 48 #include "weborigin/KnownPorts.h"
49 #include "weborigin/SchemeRegistry.h" 49 #include "weborigin/SchemeRegistry.h"
50 #include "weborigin/SecurityOrigin.h" 50 #include "weborigin/SecurityOrigin.h"
51 #include "wtf/HashSet.h" 51 #include "wtf/HashSet.h"
52 #include "wtf/SHA1.h"
53 #include "wtf/text/Base64.h"
54 #include "wtf/text/StringBuilder.h"
52 #include "wtf/text/TextPosition.h" 55 #include "wtf/text/TextPosition.h"
53 #include "wtf/text/WTFString.h" 56 #include "wtf/text/WTFString.h"
54 57
55 namespace WebCore { 58 namespace WebCore {
56 59
57 // Normally WebKit uses "static" for internal linkage, but using "static" for 60 // Normally WebKit uses "static" for internal linkage, but using "static" for
58 // these functions causes a compile error because these functions are used as 61 // these functions causes a compile error because these functions are used as
59 // template parameters. 62 // template parameters.
60 namespace { 63 namespace {
61 64
62 bool isDirectiveNameCharacter(UChar c) 65 bool isDirectiveNameCharacter(UChar c)
63 { 66 {
64 return isASCIIAlphanumeric(c) || c == '-'; 67 return isASCIIAlphanumeric(c) || c == '-';
65 } 68 }
66 69
67 bool isDirectiveValueCharacter(UChar c) 70 bool isDirectiveValueCharacter(UChar c)
68 { 71 {
69 return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR 72 return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR
70 } 73 }
71 74
72 bool isNonceCharacter(UChar c) 75 // Only checks for general Base64 encoded chars, not '=' chars since '=' is
76 // positional and may only appear at the end of a Base64 encoded string.
77 bool isBase64EncodedCharacter(UChar c)
73 { 78 {
74 return isASCIIAlphanumeric(c) || c == '+' || c == '/'; 79 return isASCIIAlphanumeric(c) || c == '+' || c == '/';
75 } 80 }
76 81
77 bool isSourceCharacter(UChar c) 82 bool isSourceCharacter(UChar c)
78 { 83 {
79 return !isASCIISpace(c); 84 return !isASCIISpace(c);
80 } 85 }
81 86
82 bool isPathComponentCharacter(UChar c) 87 bool isPathComponentCharacter(UChar c)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 static const char sandbox[] = "sandbox"; 126 static const char sandbox[] = "sandbox";
122 static const char scriptSrc[] = "script-src"; 127 static const char scriptSrc[] = "script-src";
123 static const char styleSrc[] = "style-src"; 128 static const char styleSrc[] = "style-src";
124 129
125 // CSP 1.1 Directives 130 // CSP 1.1 Directives
126 static const char baseURI[] = "base-uri"; 131 static const char baseURI[] = "base-uri";
127 static const char formAction[] = "form-action"; 132 static const char formAction[] = "form-action";
128 static const char pluginTypes[] = "plugin-types"; 133 static const char pluginTypes[] = "plugin-types";
129 static const char reflectedXSS[] = "reflected-xss"; 134 static const char reflectedXSS[] = "reflected-xss";
130 135
136 // Supported script hashes and their prefix name
137 static const char sha1Label[] = "sha1";
138 static const char sha256Label[] = "sha256";
139
131 bool isDirectiveName(const String& name) 140 bool isDirectiveName(const String& name)
132 { 141 {
133 return (equalIgnoringCase(name, connectSrc) 142 return (equalIgnoringCase(name, connectSrc)
134 || equalIgnoringCase(name, defaultSrc) 143 || equalIgnoringCase(name, defaultSrc)
135 || equalIgnoringCase(name, fontSrc) 144 || equalIgnoringCase(name, fontSrc)
136 || equalIgnoringCase(name, frameSrc) 145 || equalIgnoringCase(name, frameSrc)
137 || equalIgnoringCase(name, imgSrc) 146 || equalIgnoringCase(name, imgSrc)
138 || equalIgnoringCase(name, mediaSrc) 147 || equalIgnoringCase(name, mediaSrc)
139 || equalIgnoringCase(name, objectSrc) 148 || equalIgnoringCase(name, objectSrc)
140 || equalIgnoringCase(name, reportURI) 149 || equalIgnoringCase(name, reportURI)
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 class CSPSourceList { 281 class CSPSourceList {
273 public: 282 public:
274 CSPSourceList(ContentSecurityPolicy*, const String& directiveName); 283 CSPSourceList(ContentSecurityPolicy*, const String& directiveName);
275 284
276 void parse(const UChar* begin, const UChar* end); 285 void parse(const UChar* begin, const UChar* end);
277 286
278 bool matches(const KURL&); 287 bool matches(const KURL&);
279 bool allowInline() const { return m_allowInline; } 288 bool allowInline() const { return m_allowInline; }
280 bool allowEval() const { return m_allowEval; } 289 bool allowEval() const { return m_allowEval; }
281 bool allowNonce(const String& nonce) const { return !nonce.isNull() && m_non ces.contains(nonce); } 290 bool allowNonce(const String& nonce) const { return !nonce.isNull() && m_non ces.contains(nonce); }
291 bool allowHash(const String& hash) const { return !hash.isNull() && m_hashes .contains(hash); }
282 292
283 private: 293 private:
284 bool parseSource(const UChar* begin, const UChar* end, String& scheme, Strin g& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard); 294 bool parseSource(const UChar* begin, const UChar* end, String& scheme, Strin g& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
285 bool parseScheme(const UChar* begin, const UChar* end, String& scheme); 295 bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
286 bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hos tHasWildcard); 296 bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hos tHasWildcard);
287 bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHa sWildcard); 297 bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHa sWildcard);
288 bool parsePath(const UChar* begin, const UChar* end, String& path); 298 bool parsePath(const UChar* begin, const UChar* end, String& path);
289 bool parseNonce(const UChar* begin, const UChar* end, String& nonce); 299 bool parseNonce(const UChar* begin, const UChar* end, String& nonce);
300 bool parseHash(const UChar* begin, const UChar* end, String& hash);
290 301
291 void addSourceSelf(); 302 void addSourceSelf();
292 void addSourceStar(); 303 void addSourceStar();
293 void addSourceUnsafeInline(); 304 void addSourceUnsafeInline();
294 void addSourceUnsafeEval(); 305 void addSourceUnsafeEval();
295 void addSourceNonce(const String& nonce); 306 void addSourceNonce(const String& nonce);
307 void addSourceHash(const String& hash);
296 308
297 ContentSecurityPolicy* m_policy; 309 ContentSecurityPolicy* m_policy;
298 Vector<CSPSource> m_list; 310 Vector<CSPSource> m_list;
299 String m_directiveName; 311 String m_directiveName;
300 bool m_allowStar; 312 bool m_allowStar;
301 bool m_allowInline; 313 bool m_allowInline;
302 bool m_allowEval; 314 bool m_allowEval;
303 HashSet<String> m_nonces; 315 HashSet<String> m_nonces;
316 HashSet<String> m_hashes;
304 }; 317 };
305 318
306 CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& direct iveName) 319 CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& direct iveName)
307 : m_policy(policy) 320 : m_policy(policy)
308 , m_directiveName(directiveName) 321 , m_directiveName(directiveName)
309 , m_allowStar(false) 322 , m_allowStar(false)
310 , m_allowInline(false) 323 , m_allowInline(false)
311 , m_allowEval(false) 324 , m_allowEval(false)
312 { 325 {
313 } 326 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 415
403 if (m_policy->experimentalFeaturesEnabled()) { 416 if (m_policy->experimentalFeaturesEnabled()) {
404 String nonce; 417 String nonce;
405 if (!parseNonce(begin, end, nonce)) 418 if (!parseNonce(begin, end, nonce))
406 return false; 419 return false;
407 420
408 if (!nonce.isNull()) { 421 if (!nonce.isNull()) {
409 addSourceNonce(nonce); 422 addSourceNonce(nonce);
410 return true; 423 return true;
411 } 424 }
425
426 String hash;
427 if (!parseHash(begin, end, hash))
428 return false;
429
430 if (!hash.isNull()) {
431 addSourceHash(hash);
432 return true;
433 }
412 } 434 }
413 435
414 const UChar* position = begin; 436 const UChar* position = begin;
415 const UChar* beginHost = begin; 437 const UChar* beginHost = begin;
416 const UChar* beginPath = end; 438 const UChar* beginPath = end;
417 const UChar* beginPort = 0; 439 const UChar* beginPort = 0;
418 440
419 skipWhile<UChar, isNotColonOrSlash>(position, end); 441 skipWhile<UChar, isNotColonOrSlash>(position, end);
420 442
421 if (position == end) { 443 if (position == end) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& non ce) 513 bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& non ce)
492 { 514 {
493 DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-")); 515 DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-"));
494 516
495 if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length( ))) 517 if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length( )))
496 return true; 518 return true;
497 519
498 const UChar* position = begin + noncePrefix.length(); 520 const UChar* position = begin + noncePrefix.length();
499 const UChar* nonceBegin = position; 521 const UChar* nonceBegin = position;
500 522
501 skipWhile<UChar, isNonceCharacter>(position, end); 523 skipWhile<UChar, isBase64EncodedCharacter>(position, end);
502 ASSERT(nonceBegin <= position); 524 ASSERT(nonceBegin <= position);
503 525
504 if (((position + 1) != end && *position != '\'') || !(position - nonceBegin )) 526 if (((position + 1) != end && *position != '\'') || !(position - nonceBegin ))
505 return false; 527 return false;
506 528
507 nonce = String(nonceBegin, position - nonceBegin); 529 nonce = String(nonceBegin, position - nonceBegin);
508 return true; 530 return true;
509 } 531 }
510 532
533 // hash-source = "'" hash-algorithm "-" hash-value "'"
534 // hash-algorithm = "sha1" / "sha256"
535 // hash-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
536 //
537 bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, String& hash )
538 {
539 // TODO(jww) For now, we are not supporting SHA-256 (or any hashes other
540 // than SHA-1), so we need to put in a log message here to indicate that.
541 StringBuilder sha1Prefix;
542 sha1Prefix.append("'");
543 sha1Prefix.append(sha1Label);
544 sha1Prefix.append("-");
abarth-chromium 2013/10/17 02:28:09 There's no reason to use a StringBuilder here. Yo
jww 2013/10/18 22:58:04 Done.
545 bool isSha1 = equalIgnoringCase(sha1Prefix.toString().characters8(), begin, sha1Prefix.length());
546 StringBuilder sha256Prefix;
547 sha256Prefix.append("'");
548 sha256Prefix.append(sha256Label);
549 sha256Prefix.append("-");
550 bool isSha256 = equalIgnoringCase(sha256Prefix.toString().characters8(), beg in, sha256Prefix.length());
abarth-chromium 2013/10/17 02:28:09 Ditto
jww 2013/10/18 22:58:04 Done.
551
552 if (!isSha1)
553 return true;
abarth-chromium 2013/10/17 02:28:09 You should call notImplemented() for the isSha256
jww 2013/10/18 22:58:04 Done.
554
555 const UChar* position = begin + (isSha1 ? sha1Prefix.length() : sha256Prefix .length());
556 const UChar* hashBegin = position;
557
558 skipWhile<UChar, isBase64EncodedCharacter>(position, end);
559 ASSERT(hashBegin <= position);
560
561 // Base64 encodings may end with exactly one or two '=' characters
562 for (size_t i = 0; i < 2 && position != end; i++) {
563 if (*position != '=')
564 break;
565 position = position + 1;
566 }
567
568 if (((position + 1) != end && *position != '\'') || !(position - hashBegin) )
569 return false;
570
571 hash = String(begin + 1, position - begin - 1);
572 return true;
573 }
574
511 // ; <scheme> production from RFC 3986 575 // ; <scheme> production from RFC 3986
512 // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 576 // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
513 // 577 //
514 bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& sc heme) 578 bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& sc heme)
515 { 579 {
516 ASSERT(begin <= end); 580 ASSERT(begin <= end);
517 ASSERT(scheme.isEmpty()); 581 ASSERT(scheme.isEmpty());
518 582
519 if (begin == end) 583 if (begin == end)
520 return false; 584 return false;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 void CSPSourceList::addSourceUnsafeEval() 707 void CSPSourceList::addSourceUnsafeEval()
644 { 708 {
645 m_allowEval = true; 709 m_allowEval = true;
646 } 710 }
647 711
648 void CSPSourceList::addSourceNonce(const String& nonce) 712 void CSPSourceList::addSourceNonce(const String& nonce)
649 { 713 {
650 m_nonces.add(nonce); 714 m_nonces.add(nonce);
651 } 715 }
652 716
717 void CSPSourceList::addSourceHash(const String& hash)
718 {
719 m_hashes.add(hash);
720 }
721
653 class CSPDirective { 722 class CSPDirective {
654 public: 723 public:
655 CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy) 724 CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
656 : m_name(name) 725 : m_name(name)
657 , m_text(name + ' ' + value) 726 , m_text(name + ' ' + value)
658 , m_policy(policy) 727 , m_policy(policy)
659 { 728 {
660 } 729 }
661 730
662 const String& text() const { return m_text; } 731 const String& text() const { return m_text; }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 } 828 }
760 829
761 bool allows(const KURL& url) 830 bool allows(const KURL& url)
762 { 831 {
763 return m_sourceList.matches(url.isEmpty() ? policy()->url() : url); 832 return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
764 } 833 }
765 834
766 bool allowInline() const { return m_sourceList.allowInline(); } 835 bool allowInline() const { return m_sourceList.allowInline(); }
767 bool allowEval() const { return m_sourceList.allowEval(); } 836 bool allowEval() const { return m_sourceList.allowEval(); }
768 bool allowNonce(const String& nonce) const { return m_sourceList.allowNonce( nonce.stripWhiteSpace()); } 837 bool allowNonce(const String& nonce) const { return m_sourceList.allowNonce( nonce.stripWhiteSpace()); }
838 bool allowHash(const String& hash) const { return m_sourceList.allowHash(has h); }
769 839
770 private: 840 private:
771 CSPSourceList m_sourceList; 841 CSPSourceList m_sourceList;
772 }; 842 };
773 843
774 class CSPDirectiveList { 844 class CSPDirectiveList {
775 WTF_MAKE_FAST_ALLOCATED; 845 WTF_MAKE_FAST_ALLOCATED;
776 public: 846 public:
777 static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UCh ar* begin, const UChar* end, ContentSecurityPolicy::HeaderType); 847 static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UCh ar* begin, const UChar* end, ContentSecurityPolicy::HeaderType);
778 848
(...skipping 14 matching lines...) Expand all
793 bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::Reporting Status) const; 863 bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::Reporting Status) const;
794 bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; 864 bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const;
795 bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; 865 bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const;
796 bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus ) const; 866 bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus ) const;
797 bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; 867 bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const;
798 bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; 868 bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const;
799 bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) co nst; 869 bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) co nst;
800 bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const ; 870 bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const ;
801 bool allowScriptNonce(const String&) const; 871 bool allowScriptNonce(const String&) const;
802 bool allowStyleNonce(const String&) const; 872 bool allowStyleNonce(const String&) const;
873 bool allowHash(const String&) const;
803 874
804 void gatherReportURIs(DOMStringList&) const; 875 void gatherReportURIs(DOMStringList&) const;
805 const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorM essage; } 876 const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorM essage; }
806 ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflected XSSDisposition; } 877 ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflected XSSDisposition; }
807 bool isReportOnly() const { return m_reportOnly; } 878 bool isReportOnly() const { return m_reportOnly; }
808 const Vector<KURL>& reportURIs() const { return m_reportURIs; } 879 const Vector<KURL>& reportURIs() const { return m_reportURIs; }
809 880
810 private: 881 private:
811 CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType); 882 CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType);
812 883
813 bool parseDirective(const UChar* begin, const UChar* end, String& name, Stri ng& value); 884 bool parseDirective(const UChar* begin, const UChar* end, String& name, Stri ng& value);
814 void parseReportURI(const String& name, const String& value); 885 void parseReportURI(const String& name, const String& value);
815 void parsePluginTypes(const String& name, const String& value); 886 void parsePluginTypes(const String& name, const String& value);
816 void parseReflectedXSS(const String& name, const String& value); 887 void parseReflectedXSS(const String& name, const String& value);
817 void addDirective(const String& name, const String& value); 888 void addDirective(const String& name, const String& value);
818 void applySandboxPolicy(const String& name, const String& sandboxPolicy); 889 void applySandboxPolicy(const String& name, const String& sandboxPolicy);
819 890
820 template <class CSPDirectiveType> 891 template <class CSPDirectiveType>
821 void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDire ctiveType>&); 892 void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDire ctiveType>&);
822 893
823 SourceListDirective* operativeDirective(SourceListDirective*) const; 894 SourceListDirective* operativeDirective(SourceListDirective*) const;
824 void reportViolation(const String& directiveText, const String& effectiveDir ective, const String& consoleMessage, const KURL& blockedURL) const; 895 void reportViolation(const String& directiveText, const String& effectiveDir ective, const String& consoleMessage, const KURL& blockedURL) const;
825 void reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const; 896 void reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
826 void reportViolationWithState(const String& directiveText, const String& eff ectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptSta te*) const; 897 void reportViolationWithState(const String& directiveText, const String& eff ectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptSta te*) const;
827 898
828 bool checkEval(SourceListDirective*) const; 899 bool checkEval(SourceListDirective*) const;
829 bool checkInline(SourceListDirective*) const; 900 bool checkInline(SourceListDirective*) const;
830 bool checkNonce(SourceListDirective*, const String&) const; 901 bool checkNonce(SourceListDirective*, const String&) const;
902 bool checkHash(SourceListDirective*, const String&) const;
831 bool checkSource(SourceListDirective*, const KURL&) const; 903 bool checkSource(SourceListDirective*, const KURL&) const;
832 bool checkMediaType(MediaListDirective*, const String& type, const String& t ypeAttribute) const; 904 bool checkMediaType(MediaListDirective*, const String& type, const String& t ypeAttribute) const;
833 905
834 void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisable dErrorMessage = errorMessage; } 906 void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisable dErrorMessage = errorMessage; }
835 907
836 bool checkEvalAndReportViolation(SourceListDirective*, const String& console Message, ScriptState*) const; 908 bool checkEvalAndReportViolation(SourceListDirective*, const String& console Message, ScriptState*) const;
837 bool checkInlineAndReportViolation(SourceListDirective*, const String& conso leMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const; 909 bool checkInlineAndReportViolation(SourceListDirective*, const String& conso leMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
838 910
839 bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const; 911 bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const;
840 bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& typ e, const String& typeAttribute, const String& consoleMessage) const; 912 bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& typ e, const String& typeAttribute, const String& consoleMessage) const;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 bool CSPDirectiveList::checkInline(SourceListDirective* directive) const 995 bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
924 { 996 {
925 return !directive || directive->allowInline(); 997 return !directive || directive->allowInline();
926 } 998 }
927 999
928 bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const 1000 bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const
929 { 1001 {
930 return !directive || directive->allowNonce(nonce); 1002 return !directive || directive->allowNonce(nonce);
931 } 1003 }
932 1004
1005 bool CSPDirectiveList::checkHash(SourceListDirective* directive, const String& h ash) const
1006 {
1007 return !directive || directive->allowHash(hash);
1008 }
1009
933 bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& u rl) const 1010 bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& u rl) const
934 { 1011 {
935 return !directive || directive->allows(url); 1012 return !directive || directive->allows(url);
936 } 1013 }
937 1014
938 bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const Strin g& type, const String& typeAttribute) const 1015 bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const Strin g& type, const String& typeAttribute) const
939 { 1016 {
940 if (!directive) 1017 if (!directive)
941 return true; 1018 return true;
942 if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type) 1019 if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 bool CSPDirectiveList::allowScriptNonce(const String& nonce) const 1245 bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
1169 { 1246 {
1170 return checkNonce(operativeDirective(m_scriptSrc.get()), nonce); 1247 return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
1171 } 1248 }
1172 1249
1173 bool CSPDirectiveList::allowStyleNonce(const String& nonce) const 1250 bool CSPDirectiveList::allowStyleNonce(const String& nonce) const
1174 { 1251 {
1175 return checkNonce(operativeDirective(m_styleSrc.get()), nonce); 1252 return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
1176 } 1253 }
1177 1254
1255 bool CSPDirectiveList::allowHash(const String& hash) const
1256 {
1257 return checkHash(operativeDirective(m_scriptSrc.get()), hash);
abarth-chromium 2013/10/17 02:28:09 Notice the m_scriptSrc here.
jww 2013/10/18 22:58:04 Ah, right, that's why we have separate script and
1258 }
1259
1178 // policy = directive-list 1260 // policy = directive-list
1179 // directive-list = [ directive *( ";" [ directive ] ) ] 1261 // directive-list = [ directive *( ";" [ directive ] ) ]
1180 // 1262 //
1181 void CSPDirectiveList::parse(const UChar* begin, const UChar* end) 1263 void CSPDirectiveList::parse(const UChar* begin, const UChar* end)
1182 { 1264 {
1183 m_header = String(begin, end - begin); 1265 m_header = String(begin, end - begin);
1184 1266
1185 if (begin == end) 1267 if (begin == end)
1186 return; 1268 return;
1187 1269
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 1599
1518 template<bool (CSPDirectiveList::*allowed)(const String&) const> 1600 template<bool (CSPDirectiveList::*allowed)(const String&) const>
1519 bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const Strin g& nonce) 1601 bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const Strin g& nonce)
1520 { 1602 {
1521 for (size_t i = 0; i < policies.size(); ++i) { 1603 for (size_t i = 0; i < policies.size(); ++i) {
1522 if (!(policies[i].get()->*allowed)(nonce)) 1604 if (!(policies[i].get()->*allowed)(nonce))
1523 return false; 1605 return false;
1524 } 1606 }
1525 return true; 1607 return true;
1526 } 1608 }
1609
1610 template<bool (CSPDirectiveList::*allowed)(const String&) const>
1611 bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const String & hash)
1612 {
1613 for (size_t i = 0; i < policies.size(); ++i) {
1614 if (!(policies[i].get()->*allowed)(hash))
1615 return false;
1616 }
1617 return true;
1618 }
1619
1527 template<bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPoli cy::ReportingStatus) const> 1620 template<bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPoli cy::ReportingStatus) const>
1528 bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u rl, ContentSecurityPolicy::ReportingStatus reportingStatus) 1621 bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u rl, ContentSecurityPolicy::ReportingStatus reportingStatus)
1529 { 1622 {
1530 if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol())) 1623 if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
1531 return true; 1624 return true;
1532 1625
1533 for (size_t i = 0; i < policies.size(); ++i) { 1626 for (size_t i = 0; i < policies.size(); ++i) {
1534 if (!(policies[i].get()->*allowFromURL)(url, reportingStatus)) 1627 if (!(policies[i].get()->*allowFromURL)(url, reportingStatus))
1535 return false; 1628 return false;
1536 } 1629 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 bool ContentSecurityPolicy::allowScriptNonce(const String& nonce) const 1683 bool ContentSecurityPolicy::allowScriptNonce(const String& nonce) const
1591 { 1684 {
1592 return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_polici es, nonce); 1685 return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_polici es, nonce);
1593 } 1686 }
1594 1687
1595 bool ContentSecurityPolicy::allowStyleNonce(const String& nonce) const 1688 bool ContentSecurityPolicy::allowStyleNonce(const String& nonce) const
1596 { 1689 {
1597 return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policie s, nonce); 1690 return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policie s, nonce);
1598 } 1691 }
1599 1692
1693 bool ContentSecurityPolicy::allowHash(const String& source) const
1694 {
1695 // TODO(jww) We don't currently have a WTF SHA256 implementation. Once we
1696 // have that, we should implement a proper check for sha256 hash values here .
1697 SHA1 sourceSha1;
1698 sourceSha1.addBytes(source.utf8());
abarth-chromium 2013/10/17 02:28:09 Woah there cowboy. There are a couple of importan
jww 2013/10/18 22:58:04 Done.
1699 Vector<uint8_t, 20> digest;
1700 sourceSha1.computeHash(digest);
1701
1702 StringBuilder hash;
abarth-chromium 2013/10/17 02:28:09 Please call |hash.reserveCapacity(...)| with the e
jww 2013/10/18 22:58:04 Done.
1703 hash.append(sha1Label);
1704 hash.append("-");
1705 hash.append(base64Encode(reinterpret_cast<char*>(digest.data()), 20));
abarth-chromium 2013/10/17 02:28:09 20 -> digest.size()
jww 2013/10/18 22:58:04 Done.
1706 return isAllowedByAllWithHash<&CSPDirectiveList::allowHash>(m_policies, hash .toString());
1707 }
1708
1600 bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url, ContentSecuri tyPolicy::ReportingStatus reportingStatus) const 1709 bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url, ContentSecuri tyPolicy::ReportingStatus reportingStatus) const
1601 { 1710 {
1602 return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_pol icies, url, reportingStatus); 1711 return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_pol icies, url, reportingStatus);
1603 } 1712 }
1604 1713
1605 bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url, ContentSe curityPolicy::ReportingStatus reportingStatus) const 1714 bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url, ContentSe curityPolicy::ReportingStatus reportingStatus) const
1606 { 1715 {
1607 return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m _policies, url, reportingStatus); 1716 return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m _policies, url, reportingStatus);
1608 } 1717 }
1609 1718
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1844 { 1953 {
1845 ASSERT(invalidChar == '#' || invalidChar == '?'); 1954 ASSERT(invalidChar == '#' || invalidChar == '?');
1846 1955
1847 String ignoring = "The fragment identifier, including the '#', will be ignor ed."; 1956 String ignoring = "The fragment identifier, including the '#', will be ignor ed.";
1848 if (invalidChar == '?') 1957 if (invalidChar == '?')
1849 ignoring = "The query component, including the '?', will be ignored."; 1958 ignoring = "The query component, including the '?', will be ignored.";
1850 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring; 1959 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring;
1851 logToConsole(message); 1960 logToConsole(message);
1852 } 1961 }
1853 1962
1854 void ContentSecurityPolicy::reportInvalidNonce(const String& nonce) const
1855 {
1856 String message = "Ignoring invalid Content Security Policy script nonce: '" + nonce + "'.\n";
1857 logToConsole(message);
1858 }
1859
1860 void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiv eName, const String& source) const 1963 void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiv eName, const String& source) const
1861 { 1964 {
1862 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ign ored."; 1965 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ign ored.";
1863 if (equalIgnoringCase(source, "'none'")) 1966 if (equalIgnoringCase(source, "'none'"))
1864 message = message + " Note that 'none' has no effect unless it is the on ly expression in the source list."; 1967 message = message + " Note that 'none' has no effect unless it is the on ly expression in the source list.";
1865 logToConsole(message); 1968 logToConsole(message);
1866 } 1969 }
1867 1970
1868 void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const 1971 void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const
1869 { 1972 {
(...skipping 30 matching lines...) Expand all
1900 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. 2003 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report.
1901 return !m_violationReportsSent.contains(report.impl()->hash()); 2004 return !m_violationReportsSent.contains(report.impl()->hash());
1902 } 2005 }
1903 2006
1904 void ContentSecurityPolicy::didSendViolationReport(const String& report) 2007 void ContentSecurityPolicy::didSendViolationReport(const String& report)
1905 { 2008 {
1906 m_violationReportsSent.add(report.impl()->hash()); 2009 m_violationReportsSent.add(report.impl()->hash());
1907 } 2010 }
1908 2011
1909 } // namespace WebCore 2012 } // namespace WebCore
OLDNEW
« Source/core/frame/ContentSecurityPolicy.h ('K') | « Source/core/frame/ContentSecurityPolicy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698