Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 26 matching lines...) Expand all Loading... | |
| 37 #include "core/inspector/ScriptCallStack.h" | 37 #include "core/inspector/ScriptCallStack.h" |
| 38 #include "core/loader/DocumentLoader.h" | 38 #include "core/loader/DocumentLoader.h" |
| 39 #include "core/loader/PingLoader.h" | 39 #include "core/loader/PingLoader.h" |
| 40 #include "core/frame/ContentSecurityPolicyResponseHeaders.h" | 40 #include "core/frame/ContentSecurityPolicyResponseHeaders.h" |
| 41 #include "core/frame/Frame.h" | 41 #include "core/frame/Frame.h" |
| 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 "platform/NotImplemented.h" | |
| 47 #include "weborigin/KURL.h" | 48 #include "weborigin/KURL.h" |
| 48 #include "weborigin/KnownPorts.h" | 49 #include "weborigin/KnownPorts.h" |
| 49 #include "weborigin/SchemeRegistry.h" | 50 #include "weborigin/SchemeRegistry.h" |
| 50 #include "weborigin/SecurityOrigin.h" | 51 #include "weborigin/SecurityOrigin.h" |
| 51 #include "wtf/HashSet.h" | 52 #include "wtf/HashSet.h" |
| 53 #include "wtf/SHA1.h" | |
| 54 #include "wtf/text/Base64.h" | |
| 55 #include "wtf/text/StringBuilder.h" | |
| 52 #include "wtf/text/TextPosition.h" | 56 #include "wtf/text/TextPosition.h" |
| 53 #include "wtf/text/WTFString.h" | 57 #include "wtf/text/WTFString.h" |
| 54 | 58 |
| 55 namespace WebCore { | 59 namespace WebCore { |
| 56 | 60 |
| 57 // Normally WebKit uses "static" for internal linkage, but using "static" for | 61 // Normally WebKit uses "static" for internal linkage, but using "static" for |
| 58 // these functions causes a compile error because these functions are used as | 62 // these functions causes a compile error because these functions are used as |
| 59 // template parameters. | 63 // template parameters. |
| 60 namespace { | 64 namespace { |
| 61 | 65 |
| 62 bool isDirectiveNameCharacter(UChar c) | 66 bool isDirectiveNameCharacter(UChar c) |
| 63 { | 67 { |
| 64 return isASCIIAlphanumeric(c) || c == '-'; | 68 return isASCIIAlphanumeric(c) || c == '-'; |
| 65 } | 69 } |
| 66 | 70 |
| 67 bool isDirectiveValueCharacter(UChar c) | 71 bool isDirectiveValueCharacter(UChar c) |
| 68 { | 72 { |
| 69 return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR | 73 return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR |
| 70 } | 74 } |
| 71 | 75 |
| 72 bool isNonceCharacter(UChar c) | 76 // Only checks for general Base64 encoded chars, not '=' chars since '=' is |
| 77 // positional and may only appear at the end of a Base64 encoded string. | |
| 78 bool isBase64EncodedCharacter(UChar c) | |
| 73 { | 79 { |
| 74 return isASCIIAlphanumeric(c) || c == '+' || c == '/'; | 80 return isASCIIAlphanumeric(c) || c == '+' || c == '/'; |
| 75 } | 81 } |
| 76 | 82 |
| 77 bool isSourceCharacter(UChar c) | 83 bool isSourceCharacter(UChar c) |
| 78 { | 84 { |
| 79 return !isASCIISpace(c); | 85 return !isASCIISpace(c); |
| 80 } | 86 } |
| 81 | 87 |
| 82 bool isPathComponentCharacter(UChar c) | 88 bool isPathComponentCharacter(UChar c) |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 class CSPSourceList { | 278 class CSPSourceList { |
| 273 public: | 279 public: |
| 274 CSPSourceList(ContentSecurityPolicy*, const String& directiveName); | 280 CSPSourceList(ContentSecurityPolicy*, const String& directiveName); |
| 275 | 281 |
| 276 void parse(const UChar* begin, const UChar* end); | 282 void parse(const UChar* begin, const UChar* end); |
| 277 | 283 |
| 278 bool matches(const KURL&); | 284 bool matches(const KURL&); |
| 279 bool allowInline() const { return m_allowInline; } | 285 bool allowInline() const { return m_allowInline; } |
| 280 bool allowEval() const { return m_allowEval; } | 286 bool allowEval() const { return m_allowEval; } |
| 281 bool allowNonce(const String& nonce) const { return !nonce.isNull() && m_non ces.contains(nonce); } | 287 bool allowNonce(const String& nonce) const { return !nonce.isNull() && m_non ces.contains(nonce); } |
| 288 bool allowHash(const String& hash) const { return !hash.isNull() && m_hashes .contains(hash); } | |
| 289 uint8_t getHashFunctionsUsed() const { return m_hashFunctionsUsed; } | |
|
abarth-chromium
2013/10/22 17:46:49
getHashFunctionsUsed -> hashFunctionsUsed
(The "g
jww
2013/10/28 19:36:23
Done.
| |
| 282 | 290 |
| 283 private: | 291 private: |
| 284 bool parseSource(const UChar* begin, const UChar* end, String& scheme, Strin g& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard); | 292 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); | 293 bool parseScheme(const UChar* begin, const UChar* end, String& scheme); |
| 286 bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hos tHasWildcard); | 294 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); | 295 bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHa sWildcard); |
| 288 bool parsePath(const UChar* begin, const UChar* end, String& path); | 296 bool parsePath(const UChar* begin, const UChar* end, String& path); |
| 289 bool parseNonce(const UChar* begin, const UChar* end, String& nonce); | 297 bool parseNonce(const UChar* begin, const UChar* end, String& nonce); |
| 298 bool parseHash(const UChar* begin, const UChar* end, String& hash, ContentSe curityPolicy::HashFunctions&); | |
| 290 | 299 |
| 291 void addSourceSelf(); | 300 void addSourceSelf(); |
| 292 void addSourceStar(); | 301 void addSourceStar(); |
| 293 void addSourceUnsafeInline(); | 302 void addSourceUnsafeInline(); |
| 294 void addSourceUnsafeEval(); | 303 void addSourceUnsafeEval(); |
| 295 void addSourceNonce(const String& nonce); | 304 void addSourceNonce(const String& nonce); |
| 305 void addSourceHash(const String& hash, const ContentSecurityPolicy::HashFunc tions&); | |
| 296 | 306 |
| 297 ContentSecurityPolicy* m_policy; | 307 ContentSecurityPolicy* m_policy; |
| 298 Vector<CSPSource> m_list; | 308 Vector<CSPSource> m_list; |
| 299 String m_directiveName; | 309 String m_directiveName; |
| 300 bool m_allowStar; | 310 bool m_allowStar; |
| 301 bool m_allowInline; | 311 bool m_allowInline; |
| 302 bool m_allowEval; | 312 bool m_allowEval; |
| 303 HashSet<String> m_nonces; | 313 HashSet<String> m_nonces; |
| 314 HashSet<String> m_hashes; | |
| 315 uint8_t m_hashFunctionsUsed; | |
|
abarth-chromium
2013/10/22 17:46:49
Don't we need to keep track of which hash function
jww
2013/10/28 19:36:23
Fixed by other changes.
| |
| 304 }; | 316 }; |
| 305 | 317 |
| 306 CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& direct iveName) | 318 CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& direct iveName) |
| 307 : m_policy(policy) | 319 : m_policy(policy) |
| 308 , m_directiveName(directiveName) | 320 , m_directiveName(directiveName) |
| 309 , m_allowStar(false) | 321 , m_allowStar(false) |
| 310 , m_allowInline(false) | 322 , m_allowInline(false) |
| 311 , m_allowEval(false) | 323 , m_allowEval(false) |
| 324 , m_hashFunctionsUsed(0) | |
| 312 { | 325 { |
| 313 } | 326 } |
| 314 | 327 |
| 315 bool CSPSourceList::matches(const KURL& url) | 328 bool CSPSourceList::matches(const KURL& url) |
| 316 { | 329 { |
| 317 if (m_allowStar) | 330 if (m_allowStar) |
| 318 return true; | 331 return true; |
| 319 | 332 |
| 320 KURL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin: :extractInnerURL(url) : url; | 333 KURL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin: :extractInnerURL(url) : url; |
| 321 | 334 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 ContentSecurityPolicy::HashFunctions hashFunction = ContentSecurityPolic y::HashFunctionsNone; | |
| 428 if (!parseHash(begin, end, hash, hashFunction)) | |
| 429 return false; | |
| 430 | |
| 431 if (!hash.isNull()) { | |
| 432 addSourceHash(hash, hashFunction); | |
| 433 return true; | |
| 434 } | |
| 412 } | 435 } |
| 413 | 436 |
| 414 const UChar* position = begin; | 437 const UChar* position = begin; |
| 415 const UChar* beginHost = begin; | 438 const UChar* beginHost = begin; |
| 416 const UChar* beginPath = end; | 439 const UChar* beginPath = end; |
| 417 const UChar* beginPort = 0; | 440 const UChar* beginPort = 0; |
| 418 | 441 |
| 419 skipWhile<UChar, isNotColonOrSlash>(position, end); | 442 skipWhile<UChar, isNotColonOrSlash>(position, end); |
| 420 | 443 |
| 421 if (position == end) { | 444 if (position == end) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 491 bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& non ce) | 514 bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& non ce) |
| 492 { | 515 { |
| 493 DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-")); | 516 DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-")); |
| 494 | 517 |
| 495 if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length( ))) | 518 if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length( ))) |
| 496 return true; | 519 return true; |
| 497 | 520 |
| 498 const UChar* position = begin + noncePrefix.length(); | 521 const UChar* position = begin + noncePrefix.length(); |
| 499 const UChar* nonceBegin = position; | 522 const UChar* nonceBegin = position; |
| 500 | 523 |
| 501 skipWhile<UChar, isNonceCharacter>(position, end); | 524 skipWhile<UChar, isBase64EncodedCharacter>(position, end); |
| 502 ASSERT(nonceBegin <= position); | 525 ASSERT(nonceBegin <= position); |
| 503 | 526 |
| 504 if (((position + 1) != end && *position != '\'') || !(position - nonceBegin )) | 527 if (((position + 1) != end && *position != '\'') || !(position - nonceBegin )) |
| 505 return false; | 528 return false; |
| 506 | 529 |
| 507 nonce = String(nonceBegin, position - nonceBegin); | 530 nonce = String(nonceBegin, position - nonceBegin); |
| 508 return true; | 531 return true; |
| 509 } | 532 } |
| 510 | 533 |
| 534 // hash-source = "'" hash-algorithm "-" hash-value "'" | |
| 535 // hash-algorithm = "sha1" / "sha256" | |
| 536 // hash-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" ) | |
| 537 // | |
| 538 bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, String& hash , ContentSecurityPolicy::HashFunctions& hashFunction) | |
| 539 { | |
| 540 DEFINE_STATIC_LOCAL(const String, sha1Prefix, ("'sha1-")); | |
| 541 DEFINE_STATIC_LOCAL(const String, sha256Prefix, ("'sha256-")); | |
| 542 | |
| 543 String prefix; | |
| 544 if (equalIgnoringCase(sha1Prefix.characters8(), begin, sha1Prefix.length())) { | |
| 545 prefix = sha1Prefix; | |
| 546 hashFunction = ContentSecurityPolicy::HashFunctionsSha1; | |
| 547 } else if (equalIgnoringCase(sha256Prefix.characters8(), begin, sha256Prefix .length())) { | |
| 548 notImplemented(); | |
| 549 } else { | |
| 550 return true; | |
| 551 } | |
| 552 | |
| 553 const UChar* position = begin + prefix.length(); | |
| 554 const UChar* hashBegin = position; | |
| 555 | |
| 556 skipWhile<UChar, isBase64EncodedCharacter>(position, end); | |
| 557 ASSERT(hashBegin <= position); | |
| 558 | |
| 559 // Base64 encodings may end with exactly one or two '=' characters | |
| 560 skipExactly<UChar>(position, position + 1, '='); | |
| 561 skipExactly<UChar>(position, position + 1, '='); | |
| 562 | |
| 563 if (((position + 1) != end && *position != '\'') || !(position - hashBegin) ) | |
| 564 return false; | |
|
abarth-chromium
2013/10/22 17:46:49
Is this logic right? I would have expected:
if (
jww
2013/10/28 19:36:23
Done.
| |
| 565 | |
| 566 hash = String(begin + 1, position - begin - 1); | |
|
abarth-chromium
2013/10/22 17:46:49
Why begin + 1 rather than hashBegin? I would have
jww
2013/10/28 19:36:23
Hashes are now stored as a struct that contain the
| |
| 567 return true; | |
| 568 } | |
| 569 | |
| 511 // ; <scheme> production from RFC 3986 | 570 // ; <scheme> production from RFC 3986 |
| 512 // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) | 571 // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) |
| 513 // | 572 // |
| 514 bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& sc heme) | 573 bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& sc heme) |
| 515 { | 574 { |
| 516 ASSERT(begin <= end); | 575 ASSERT(begin <= end); |
| 517 ASSERT(scheme.isEmpty()); | 576 ASSERT(scheme.isEmpty()); |
| 518 | 577 |
| 519 if (begin == end) | 578 if (begin == end) |
| 520 return false; | 579 return false; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 643 void CSPSourceList::addSourceUnsafeEval() | 702 void CSPSourceList::addSourceUnsafeEval() |
| 644 { | 703 { |
| 645 m_allowEval = true; | 704 m_allowEval = true; |
| 646 } | 705 } |
| 647 | 706 |
| 648 void CSPSourceList::addSourceNonce(const String& nonce) | 707 void CSPSourceList::addSourceNonce(const String& nonce) |
| 649 { | 708 { |
| 650 m_nonces.add(nonce); | 709 m_nonces.add(nonce); |
| 651 } | 710 } |
| 652 | 711 |
| 712 void CSPSourceList::addSourceHash(const String& hash, const ContentSecurityPolic y::HashFunctions& hashFunction) | |
| 713 { | |
| 714 m_hashes.add(hash); | |
| 715 m_hashFunctionsUsed |= hashFunction; | |
| 716 } | |
| 717 | |
| 653 class CSPDirective { | 718 class CSPDirective { |
| 654 public: | 719 public: |
| 655 CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy) | 720 CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy) |
| 656 : m_name(name) | 721 : m_name(name) |
| 657 , m_text(name + ' ' + value) | 722 , m_text(name + ' ' + value) |
| 658 , m_policy(policy) | 723 , m_policy(policy) |
| 659 { | 724 { |
| 660 } | 725 } |
| 661 | 726 |
| 662 const String& text() const { return m_text; } | 727 const String& text() const { return m_text; } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 759 } | 824 } |
| 760 | 825 |
| 761 bool allows(const KURL& url) | 826 bool allows(const KURL& url) |
| 762 { | 827 { |
| 763 return m_sourceList.matches(url.isEmpty() ? policy()->url() : url); | 828 return m_sourceList.matches(url.isEmpty() ? policy()->url() : url); |
| 764 } | 829 } |
| 765 | 830 |
| 766 bool allowInline() const { return m_sourceList.allowInline(); } | 831 bool allowInline() const { return m_sourceList.allowInline(); } |
| 767 bool allowEval() const { return m_sourceList.allowEval(); } | 832 bool allowEval() const { return m_sourceList.allowEval(); } |
| 768 bool allowNonce(const String& nonce) const { return m_sourceList.allowNonce( nonce.stripWhiteSpace()); } | 833 bool allowNonce(const String& nonce) const { return m_sourceList.allowNonce( nonce.stripWhiteSpace()); } |
| 834 bool allowHash(const String& hash) const { return m_sourceList.allowHash(has h); } | |
| 835 | |
| 836 uint8_t getHashFunctionsUsed() const { return m_sourceList.getHashFunctionsU sed(); } | |
| 769 | 837 |
| 770 private: | 838 private: |
| 771 CSPSourceList m_sourceList; | 839 CSPSourceList m_sourceList; |
| 772 }; | 840 }; |
| 773 | 841 |
| 774 class CSPDirectiveList { | 842 class CSPDirectiveList { |
| 775 WTF_MAKE_FAST_ALLOCATED; | 843 WTF_MAKE_FAST_ALLOCATED; |
| 776 public: | 844 public: |
| 777 static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UCh ar* begin, const UChar* end, ContentSecurityPolicy::HeaderType); | 845 static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UCh ar* begin, const UChar* end, ContentSecurityPolicy::HeaderType); |
| 778 | 846 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 793 bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::Reporting Status) const; | 861 bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::Reporting Status) const; |
| 794 bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; | 862 bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; |
| 795 bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; | 863 bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; |
| 796 bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus ) const; | 864 bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus ) const; |
| 797 bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; | 865 bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; |
| 798 bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; | 866 bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; |
| 799 bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) co nst; | 867 bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) co nst; |
| 800 bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const ; | 868 bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const ; |
| 801 bool allowScriptNonce(const String&) const; | 869 bool allowScriptNonce(const String&) const; |
| 802 bool allowStyleNonce(const String&) const; | 870 bool allowStyleNonce(const String&) const; |
| 871 bool allowScriptHash(const String&) const; | |
| 803 | 872 |
| 804 void gatherReportURIs(DOMStringList&) const; | 873 void gatherReportURIs(DOMStringList&) const; |
| 805 const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorM essage; } | 874 const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorM essage; } |
| 806 ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflected XSSDisposition; } | 875 ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflected XSSDisposition; } |
| 807 bool isReportOnly() const { return m_reportOnly; } | 876 bool isReportOnly() const { return m_reportOnly; } |
| 808 const Vector<KURL>& reportURIs() const { return m_reportURIs; } | 877 const Vector<KURL>& reportURIs() const { return m_reportURIs; } |
| 809 | 878 |
| 810 private: | 879 private: |
| 811 CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType); | 880 CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType); |
| 812 | 881 |
| 813 bool parseDirective(const UChar* begin, const UChar* end, String& name, Stri ng& value); | 882 bool parseDirective(const UChar* begin, const UChar* end, String& name, Stri ng& value); |
| 814 void parseReportURI(const String& name, const String& value); | 883 void parseReportURI(const String& name, const String& value); |
| 815 void parsePluginTypes(const String& name, const String& value); | 884 void parsePluginTypes(const String& name, const String& value); |
| 816 void parseReflectedXSS(const String& name, const String& value); | 885 void parseReflectedXSS(const String& name, const String& value); |
| 817 void addDirective(const String& name, const String& value); | 886 void addDirective(const String& name, const String& value); |
| 818 void applySandboxPolicy(const String& name, const String& sandboxPolicy); | 887 void applySandboxPolicy(const String& name, const String& sandboxPolicy); |
| 819 | 888 |
| 820 template <class CSPDirectiveType> | 889 template <class CSPDirectiveType> |
| 821 void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDire ctiveType>&); | 890 void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDire ctiveType>&); |
| 822 | 891 |
| 823 SourceListDirective* operativeDirective(SourceListDirective*) const; | 892 SourceListDirective* operativeDirective(SourceListDirective*) const; |
| 824 void reportViolation(const String& directiveText, const String& effectiveDir ective, const String& consoleMessage, const KURL& blockedURL) const; | 893 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; | 894 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; | 895 void reportViolationWithState(const String& directiveText, const String& eff ectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptSta te*) const; |
| 827 | 896 |
| 828 bool checkEval(SourceListDirective*) const; | 897 bool checkEval(SourceListDirective*) const; |
| 829 bool checkInline(SourceListDirective*) const; | 898 bool checkInline(SourceListDirective*) const; |
| 830 bool checkNonce(SourceListDirective*, const String&) const; | 899 bool checkNonce(SourceListDirective*, const String&) const; |
| 900 bool checkHash(SourceListDirective*, const String&) const; | |
| 831 bool checkSource(SourceListDirective*, const KURL&) const; | 901 bool checkSource(SourceListDirective*, const KURL&) const; |
| 832 bool checkMediaType(MediaListDirective*, const String& type, const String& t ypeAttribute) const; | 902 bool checkMediaType(MediaListDirective*, const String& type, const String& t ypeAttribute) const; |
| 833 | 903 |
| 834 void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisable dErrorMessage = errorMessage; } | 904 void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisable dErrorMessage = errorMessage; } |
| 835 | 905 |
| 836 bool checkEvalAndReportViolation(SourceListDirective*, const String& console Message, ScriptState*) const; | 906 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; | 907 bool checkInlineAndReportViolation(SourceListDirective*, const String& conso leMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const; |
| 838 | 908 |
| 839 bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const; | 909 bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const; |
| 840 bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& typ e, const String& typeAttribute, const String& consoleMessage) const; | 910 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 Loading... | |
| 923 bool CSPDirectiveList::checkInline(SourceListDirective* directive) const | 993 bool CSPDirectiveList::checkInline(SourceListDirective* directive) const |
| 924 { | 994 { |
| 925 return !directive || directive->allowInline(); | 995 return !directive || directive->allowInline(); |
| 926 } | 996 } |
| 927 | 997 |
| 928 bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const | 998 bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const |
| 929 { | 999 { |
| 930 return !directive || directive->allowNonce(nonce); | 1000 return !directive || directive->allowNonce(nonce); |
| 931 } | 1001 } |
| 932 | 1002 |
| 1003 bool CSPDirectiveList::checkHash(SourceListDirective* directive, const String& h ash) const | |
| 1004 { | |
| 1005 return !directive || directive->allowHash(hash); | |
| 1006 } | |
| 1007 | |
| 933 bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& u rl) const | 1008 bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& u rl) const |
| 934 { | 1009 { |
| 935 return !directive || directive->allows(url); | 1010 return !directive || directive->allows(url); |
| 936 } | 1011 } |
| 937 | 1012 |
| 938 bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const Strin g& type, const String& typeAttribute) const | 1013 bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const Strin g& type, const String& typeAttribute) const |
| 939 { | 1014 { |
| 940 if (!directive) | 1015 if (!directive) |
| 941 return true; | 1016 return true; |
| 942 if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type) | 1017 if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type) |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1168 bool CSPDirectiveList::allowScriptNonce(const String& nonce) const | 1243 bool CSPDirectiveList::allowScriptNonce(const String& nonce) const |
| 1169 { | 1244 { |
| 1170 return checkNonce(operativeDirective(m_scriptSrc.get()), nonce); | 1245 return checkNonce(operativeDirective(m_scriptSrc.get()), nonce); |
| 1171 } | 1246 } |
| 1172 | 1247 |
| 1173 bool CSPDirectiveList::allowStyleNonce(const String& nonce) const | 1248 bool CSPDirectiveList::allowStyleNonce(const String& nonce) const |
| 1174 { | 1249 { |
| 1175 return checkNonce(operativeDirective(m_styleSrc.get()), nonce); | 1250 return checkNonce(operativeDirective(m_styleSrc.get()), nonce); |
| 1176 } | 1251 } |
| 1177 | 1252 |
| 1253 bool CSPDirectiveList::allowScriptHash(const String& hash) const | |
| 1254 { | |
| 1255 return checkHash(operativeDirective(m_scriptSrc.get()), hash); | |
| 1256 } | |
| 1257 | |
| 1178 // policy = directive-list | 1258 // policy = directive-list |
| 1179 // directive-list = [ directive *( ";" [ directive ] ) ] | 1259 // directive-list = [ directive *( ";" [ directive ] ) ] |
| 1180 // | 1260 // |
| 1181 void CSPDirectiveList::parse(const UChar* begin, const UChar* end) | 1261 void CSPDirectiveList::parse(const UChar* begin, const UChar* end) |
| 1182 { | 1262 { |
| 1183 m_header = String(begin, end - begin); | 1263 m_header = String(begin, end - begin); |
| 1184 | 1264 |
| 1185 if (begin == end) | 1265 if (begin == end) |
| 1186 return; | 1266 return; |
| 1187 | 1267 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1351 // value1 value2 | 1431 // value1 value2 |
| 1352 // ^ | 1432 // ^ |
| 1353 m_reflectedXSSDisposition = ReflectedXSSInvalid; | 1433 m_reflectedXSSDisposition = ReflectedXSSInvalid; |
| 1354 m_policy->reportInvalidReflectedXSS(value); | 1434 m_policy->reportInvalidReflectedXSS(value); |
| 1355 } | 1435 } |
| 1356 | 1436 |
| 1357 void CSPDirectiveList::addDirective(const String& name, const String& value) | 1437 void CSPDirectiveList::addDirective(const String& name, const String& value) |
| 1358 { | 1438 { |
| 1359 ASSERT(!name.isEmpty()); | 1439 ASSERT(!name.isEmpty()); |
| 1360 | 1440 |
| 1361 if (equalIgnoringCase(name, defaultSrc)) | 1441 if (equalIgnoringCase(name, defaultSrc)) { |
| 1362 setCSPDirective<SourceListDirective>(name, value, m_defaultSrc); | 1442 setCSPDirective<SourceListDirective>(name, value, m_defaultSrc); |
| 1363 else if (equalIgnoringCase(name, scriptSrc)) | 1443 } else if (equalIgnoringCase(name, scriptSrc)) { |
| 1364 setCSPDirective<SourceListDirective>(name, value, m_scriptSrc); | 1444 setCSPDirective<SourceListDirective>(name, value, m_scriptSrc); |
| 1365 else if (equalIgnoringCase(name, objectSrc)) | 1445 m_policy->usesScriptHashFunctions(m_scriptSrc->getHashFunctionsUsed()); |
| 1446 } else if (equalIgnoringCase(name, objectSrc)) { | |
| 1366 setCSPDirective<SourceListDirective>(name, value, m_objectSrc); | 1447 setCSPDirective<SourceListDirective>(name, value, m_objectSrc); |
| 1367 else if (equalIgnoringCase(name, frameSrc)) | 1448 } else if (equalIgnoringCase(name, frameSrc)) { |
| 1368 setCSPDirective<SourceListDirective>(name, value, m_frameSrc); | 1449 setCSPDirective<SourceListDirective>(name, value, m_frameSrc); |
| 1369 else if (equalIgnoringCase(name, imgSrc)) | 1450 } else if (equalIgnoringCase(name, imgSrc)) { |
| 1370 setCSPDirective<SourceListDirective>(name, value, m_imgSrc); | 1451 setCSPDirective<SourceListDirective>(name, value, m_imgSrc); |
| 1371 else if (equalIgnoringCase(name, styleSrc)) | 1452 } else if (equalIgnoringCase(name, styleSrc)) { |
| 1372 setCSPDirective<SourceListDirective>(name, value, m_styleSrc); | 1453 setCSPDirective<SourceListDirective>(name, value, m_styleSrc); |
| 1373 else if (equalIgnoringCase(name, fontSrc)) | 1454 } else if (equalIgnoringCase(name, fontSrc)) { |
| 1374 setCSPDirective<SourceListDirective>(name, value, m_fontSrc); | 1455 setCSPDirective<SourceListDirective>(name, value, m_fontSrc); |
| 1375 else if (equalIgnoringCase(name, mediaSrc)) | 1456 } else if (equalIgnoringCase(name, mediaSrc)) { |
| 1376 setCSPDirective<SourceListDirective>(name, value, m_mediaSrc); | 1457 setCSPDirective<SourceListDirective>(name, value, m_mediaSrc); |
| 1377 else if (equalIgnoringCase(name, connectSrc)) | 1458 } else if (equalIgnoringCase(name, connectSrc)) { |
| 1378 setCSPDirective<SourceListDirective>(name, value, m_connectSrc); | 1459 setCSPDirective<SourceListDirective>(name, value, m_connectSrc); |
| 1379 else if (equalIgnoringCase(name, sandbox)) | 1460 } else if (equalIgnoringCase(name, sandbox)) { |
| 1380 applySandboxPolicy(name, value); | 1461 applySandboxPolicy(name, value); |
| 1381 else if (equalIgnoringCase(name, reportURI)) | 1462 } else if (equalIgnoringCase(name, reportURI)) { |
| 1382 parseReportURI(name, value); | 1463 parseReportURI(name, value); |
| 1383 else if (m_policy->experimentalFeaturesEnabled()) { | 1464 } else if (m_policy->experimentalFeaturesEnabled()) { |
| 1384 if (equalIgnoringCase(name, baseURI)) | 1465 if (equalIgnoringCase(name, baseURI)) |
| 1385 setCSPDirective<SourceListDirective>(name, value, m_baseURI); | 1466 setCSPDirective<SourceListDirective>(name, value, m_baseURI); |
| 1386 else if (equalIgnoringCase(name, formAction)) | 1467 else if (equalIgnoringCase(name, formAction)) |
| 1387 setCSPDirective<SourceListDirective>(name, value, m_formAction); | 1468 setCSPDirective<SourceListDirective>(name, value, m_formAction); |
| 1388 else if (equalIgnoringCase(name, pluginTypes)) | 1469 else if (equalIgnoringCase(name, pluginTypes)) |
| 1389 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); | 1470 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); |
| 1390 else if (equalIgnoringCase(name, reflectedXSS)) | 1471 else if (equalIgnoringCase(name, reflectedXSS)) |
| 1391 parseReflectedXSS(name, value); | 1472 parseReflectedXSS(name, value); |
| 1392 else | 1473 else |
| 1393 m_policy->reportUnsupportedDirective(name); | 1474 m_policy->reportUnsupportedDirective(name); |
| 1475 } else { | |
| 1476 m_policy->reportUnsupportedDirective(name); | |
| 1394 } | 1477 } |
| 1395 else | |
| 1396 m_policy->reportUnsupportedDirective(name); | |
| 1397 } | 1478 } |
| 1398 | 1479 |
| 1399 ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContext* executionContext) | 1480 ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContext* executionContext) |
| 1400 : m_executionContext(executionContext) | 1481 : m_executionContext(executionContext) |
| 1401 , m_overrideInlineStyleAllowed(false) | 1482 , m_overrideInlineStyleAllowed(false) |
| 1483 , m_sourceHashFunctionsUsed(HashFunctionsNone) | |
| 1402 { | 1484 { |
| 1403 } | 1485 } |
| 1404 | 1486 |
| 1405 ContentSecurityPolicy::~ContentSecurityPolicy() | 1487 ContentSecurityPolicy::~ContentSecurityPolicy() |
| 1406 { | 1488 { |
| 1407 } | 1489 } |
| 1408 | 1490 |
| 1409 void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other) | 1491 void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other) |
| 1410 { | 1492 { |
| 1411 ASSERT(m_policies.isEmpty()); | 1493 ASSERT(m_policies.isEmpty()); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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::allowScriptHash(const String& source) const | |
| 1694 { | |
| 1695 DEFINE_STATIC_LOCAL(const String, sha1Prefix, ("sha1-")); | |
| 1696 | |
| 1697 // TODO(jww) We don't currently have a WTF SHA256 implementation. Once we | |
| 1698 // have that, we should implement a proper check for sha256 hash values here . | |
| 1699 if (HashFunctionsSha1 & m_sourceHashFunctionsUsed) { | |
| 1700 SHA1 sourceSha1; | |
| 1701 sourceSha1.addBytes(UTF8Encoding().normalizeAndEncode(source, WTF::Entit iesForUnencodables)); | |
| 1702 Vector<uint8_t, 20> digest; | |
| 1703 sourceSha1.computeHash(digest); | |
| 1704 | |
| 1705 StringBuilder hash; | |
| 1706 hash.reserveCapacity(sha1Prefix.length() + digest.size()); | |
| 1707 hash.append(sha1Prefix); | |
| 1708 hash.append(base64Encode(reinterpret_cast<char*>(digest.data()), digest. size())); | |
|
abarth-chromium
2013/10/22 17:46:49
What about the trailing = characters? Do we need
jww
2013/10/28 19:36:23
Addressed by other changes (now storing the hash a
| |
| 1709 if (isAllowedByAllWithHash<&CSPDirectiveList::allowScriptHash>(m_policie s, hash.toString())) | |
| 1710 return true; | |
| 1711 } | |
| 1712 | |
| 1713 return false; | |
| 1714 } | |
| 1715 | |
| 1716 void ContentSecurityPolicy::usesScriptHashFunctions(uint8_t hashFunctions) | |
| 1717 { | |
| 1718 m_sourceHashFunctionsUsed |= hashFunctions; | |
| 1719 } | |
| 1720 | |
| 1600 bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url, ContentSecuri tyPolicy::ReportingStatus reportingStatus) const | 1721 bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url, ContentSecuri tyPolicy::ReportingStatus reportingStatus) const |
| 1601 { | 1722 { |
| 1602 return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_pol icies, url, reportingStatus); | 1723 return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_pol icies, url, reportingStatus); |
| 1603 } | 1724 } |
| 1604 | 1725 |
| 1605 bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url, ContentSe curityPolicy::ReportingStatus reportingStatus) const | 1726 bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url, ContentSe curityPolicy::ReportingStatus reportingStatus) const |
| 1606 { | 1727 { |
| 1607 return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m _policies, url, reportingStatus); | 1728 return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m _policies, url, reportingStatus); |
| 1608 } | 1729 } |
| 1609 | 1730 |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1844 { | 1965 { |
| 1845 ASSERT(invalidChar == '#' || invalidChar == '?'); | 1966 ASSERT(invalidChar == '#' || invalidChar == '?'); |
| 1846 | 1967 |
| 1847 String ignoring = "The fragment identifier, including the '#', will be ignor ed."; | 1968 String ignoring = "The fragment identifier, including the '#', will be ignor ed."; |
| 1848 if (invalidChar == '?') | 1969 if (invalidChar == '?') |
| 1849 ignoring = "The query component, including the '?', will be ignored."; | 1970 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; | 1971 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring; |
| 1851 logToConsole(message); | 1972 logToConsole(message); |
| 1852 } | 1973 } |
| 1853 | 1974 |
| 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 | 1975 void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiv eName, const String& source) const |
| 1861 { | 1976 { |
| 1862 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ign ored."; | 1977 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'")) | 1978 if (equalIgnoringCase(source, "'none'")) |
| 1864 message = message + " Note that 'none' has no effect unless it is the on ly expression in the source list."; | 1979 message = message + " Note that 'none' has no effect unless it is the on ly expression in the source list."; |
| 1865 logToConsole(message); | 1980 logToConsole(message); |
| 1866 } | 1981 } |
| 1867 | 1982 |
| 1868 void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const | 1983 void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const |
| 1869 { | 1984 { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1900 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. | 2015 // 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()); | 2016 return !m_violationReportsSent.contains(report.impl()->hash()); |
| 1902 } | 2017 } |
| 1903 | 2018 |
| 1904 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 2019 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
| 1905 { | 2020 { |
| 1906 m_violationReportsSent.add(report.impl()->hash()); | 2021 m_violationReportsSent.add(report.impl()->hash()); |
| 1907 } | 2022 } |
| 1908 | 2023 |
| 1909 } // namespace WebCore | 2024 } // namespace WebCore |
| OLD | NEW |