OLD | NEW |
---|---|
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 "config.h" | 5 #include "config.h" |
6 #include "core/frame/csp/CSPDirectiveList.h" | 6 #include "core/frame/csp/CSPDirectiveList.h" |
7 | 7 |
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/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
(...skipping 25 matching lines...) Expand all Loading... | |
36 return "sha256-" + base64URLEncode(reinterpret_cast<char*>(digest.data()), d igest.size(), Base64DoNotInsertLFs); | 36 return "sha256-" + base64URLEncode(reinterpret_cast<char*>(digest.data()), d igest.size(), Base64DoNotInsertLFs); |
37 } | 37 } |
38 | 38 |
39 } | 39 } |
40 | 40 |
41 CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurit yPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) | 41 CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurit yPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) |
42 : m_policy(policy) | 42 : m_policy(policy) |
43 , m_headerType(type) | 43 , m_headerType(type) |
44 , m_headerSource(source) | 44 , m_headerSource(source) |
45 , m_reportOnly(false) | 45 , m_reportOnly(false) |
46 , m_haveSandboxPolicy(false) | 46 , m_hasSandboxPolicy(false) |
47 , m_hasSuboriginPolicy(false) | |
47 , m_reflectedXSSDisposition(ReflectedXSSUnset) | 48 , m_reflectedXSSDisposition(ReflectedXSSUnset) |
48 , m_didSetReferrerPolicy(false) | 49 , m_didSetReferrerPolicy(false) |
49 , m_referrerPolicy(ReferrerPolicyDefault) | 50 , m_referrerPolicy(ReferrerPolicyDefault) |
50 , m_strictMixedContentCheckingEnforced(false) | 51 , m_strictMixedContentCheckingEnforced(false) |
51 , m_upgradeInsecureRequests(false) | 52 , m_upgradeInsecureRequests(false) |
52 { | 53 { |
53 m_reportOnly = type == ContentSecurityPolicyHeaderTypeReport; | 54 m_reportOnly = type == ContentSecurityPolicyHeaderTypeReport; |
54 } | 55 } |
55 | 56 |
56 PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* pol icy, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) | 57 PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* pol icy, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
525 } | 526 } |
526 directive = adoptPtr(new CSPDirectiveType(name, value, m_policy)); | 527 directive = adoptPtr(new CSPDirectiveType(name, value, m_policy)); |
527 } | 528 } |
528 | 529 |
529 void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sand boxPolicy) | 530 void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sand boxPolicy) |
530 { | 531 { |
531 if (m_reportOnly) { | 532 if (m_reportOnly) { |
532 m_policy->reportInvalidInReportOnly(name); | 533 m_policy->reportInvalidInReportOnly(name); |
533 return; | 534 return; |
534 } | 535 } |
535 if (m_haveSandboxPolicy) { | 536 if (m_hasSandboxPolicy) { |
536 m_policy->reportDuplicateDirective(name); | 537 m_policy->reportDuplicateDirective(name); |
537 return; | 538 return; |
538 } | 539 } |
539 m_haveSandboxPolicy = true; | 540 m_hasSandboxPolicy = true; |
540 String invalidTokens; | 541 String invalidTokens; |
541 m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidToken s)); | 542 m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidToken s)); |
542 if (!invalidTokens.isNull()) | 543 if (!invalidTokens.isNull()) |
543 m_policy->reportInvalidSandboxFlags(invalidTokens); | 544 m_policy->reportInvalidSandboxFlags(invalidTokens); |
544 } | 545 } |
545 | 546 |
546 void CSPDirectiveList::enforceStrictMixedContentChecking(const String& name, con st String& value) | 547 void CSPDirectiveList::enforceStrictMixedContentChecking(const String& name, con st String& value) |
547 { | 548 { |
548 if (m_reportOnly) { | 549 if (m_reportOnly) { |
549 m_policy->reportInvalidInReportOnly(name); | 550 m_policy->reportInvalidInReportOnly(name); |
(...skipping 19 matching lines...) Expand all Loading... | |
569 m_policy->reportDuplicateDirective(name); | 570 m_policy->reportDuplicateDirective(name); |
570 return; | 571 return; |
571 } | 572 } |
572 m_upgradeInsecureRequests = true; | 573 m_upgradeInsecureRequests = true; |
573 | 574 |
574 m_policy->setInsecureRequestsPolicy(SecurityContext::InsecureRequestsUpgrade ); | 575 m_policy->setInsecureRequestsPolicy(SecurityContext::InsecureRequestsUpgrade ); |
575 if (!value.isEmpty()) | 576 if (!value.isEmpty()) |
576 m_policy->reportValueForEmptyDirective(name, value); | 577 m_policy->reportValueForEmptyDirective(name, value); |
577 } | 578 } |
578 | 579 |
580 void CSPDirectiveList::applySuboriginPolicy(const String& name, const String& su boriginPolicy) | |
581 { | |
Mike West
2015/03/23 07:32:55
Nit: ASSERT(RuntimeEnabledFeatures::suboriginsEnab
jww
2015/04/11 02:52:36
Done.
| |
582 if (m_headerSource == ContentSecurityPolicyHeaderSourceMeta) { | |
583 m_policy->reportSuboriginInMeta(suboriginPolicy); | |
584 return; | |
585 } | |
586 | |
587 if (m_hasSuboriginPolicy) { | |
588 m_policy->reportDuplicateDirective(name); | |
589 return; | |
590 } | |
591 m_hasSuboriginPolicy = true; | |
592 String suboriginName = parseSuboriginName(suboriginPolicy); | |
593 if (!suboriginName.isNull()) | |
594 m_policy->enforceSuborigin(suboriginName); | |
595 } | |
596 | |
579 void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value ) | 597 void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value ) |
580 { | 598 { |
581 if (m_reflectedXSSDisposition != ReflectedXSSUnset) { | 599 if (m_reflectedXSSDisposition != ReflectedXSSUnset) { |
582 m_policy->reportDuplicateDirective(name); | 600 m_policy->reportDuplicateDirective(name); |
583 m_reflectedXSSDisposition = ReflectedXSSInvalid; | 601 m_reflectedXSSDisposition = ReflectedXSSInvalid; |
584 return; | 602 return; |
585 } | 603 } |
586 | 604 |
587 if (value.isEmpty()) { | 605 if (value.isEmpty()) { |
588 m_reflectedXSSDisposition = ReflectedXSSInvalid; | 606 m_reflectedXSSDisposition = ReflectedXSSInvalid; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
669 } | 687 } |
670 | 688 |
671 skipWhile<UChar, isASCIISpace>(position, end); | 689 skipWhile<UChar, isASCIISpace>(position, end); |
672 if (position == end) | 690 if (position == end) |
673 return; | 691 return; |
674 | 692 |
675 // value1 value2 | 693 // value1 value2 |
676 // ^ | 694 // ^ |
677 m_referrerPolicy = ReferrerPolicyNever; | 695 m_referrerPolicy = ReferrerPolicyNever; |
678 m_policy->reportInvalidReferrer(value); | 696 m_policy->reportInvalidReferrer(value); |
697 } | |
679 | 698 |
699 String CSPDirectiveList::parseSuboriginName(const String& policy) | |
Mike West
2015/03/23 07:32:55
We really need to add some parser unittests. Would
| |
700 { | |
701 Vector<UChar> characters; | |
702 policy.appendTo(characters); | |
703 | |
704 const UChar* position = characters.data(); | |
705 const UChar* end = position + characters.size(); | |
706 | |
707 // Parse the name of the suborigin (no spaces, single string) | |
708 skipWhile<UChar, isASCIISpace>(position, end); | |
709 if (position == end) { | |
710 m_policy->reportInvalidSuboriginFlags("No suborigin name specified."); | |
711 return String(); | |
712 } | |
713 | |
714 const UChar* begin = position; | |
715 | |
716 skipWhile<UChar, isASCIIAlphanumeric>(position, end); | |
717 if (position != end && !isASCIISpace(*position)) { | |
718 m_policy->reportInvalidSuboriginFlags("Invalid character \'" + String(po sition, 1) + "\' in suborigin."); | |
719 return String(); | |
720 } | |
721 size_t length = position - begin; | |
722 skipWhile<UChar, isASCIISpace>(position, end); | |
723 if (position != end) { | |
724 m_policy->reportInvalidSuboriginFlags("Whitespace is not allowed in subo rigin names."); | |
725 return String(); | |
726 } | |
727 | |
728 return String(begin, length); | |
680 } | 729 } |
681 | 730 |
682 void CSPDirectiveList::addDirective(const String& name, const String& value) | 731 void CSPDirectiveList::addDirective(const String& name, const String& value) |
683 { | 732 { |
684 ASSERT(!name.isEmpty()); | 733 ASSERT(!name.isEmpty()); |
685 | 734 |
686 if (equalIgnoringCase(name, ContentSecurityPolicy::DefaultSrc)) { | 735 if (equalIgnoringCase(name, ContentSecurityPolicy::DefaultSrc)) { |
687 setCSPDirective<SourceListDirective>(name, value, m_defaultSrc); | 736 setCSPDirective<SourceListDirective>(name, value, m_defaultSrc); |
688 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ScriptSrc)) { | 737 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ScriptSrc)) { |
689 setCSPDirective<SourceListDirective>(name, value, m_scriptSrc); | 738 setCSPDirective<SourceListDirective>(name, value, m_scriptSrc); |
(...skipping 24 matching lines...) Expand all Loading... | |
714 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ChildSrc)) { | 763 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ChildSrc)) { |
715 setCSPDirective<SourceListDirective>(name, value, m_childSrc); | 764 setCSPDirective<SourceListDirective>(name, value, m_childSrc); |
716 } else if (equalIgnoringCase(name, ContentSecurityPolicy::FormAction)) { | 765 } else if (equalIgnoringCase(name, ContentSecurityPolicy::FormAction)) { |
717 setCSPDirective<SourceListDirective>(name, value, m_formAction); | 766 setCSPDirective<SourceListDirective>(name, value, m_formAction); |
718 } else if (equalIgnoringCase(name, ContentSecurityPolicy::PluginTypes)) { | 767 } else if (equalIgnoringCase(name, ContentSecurityPolicy::PluginTypes)) { |
719 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); | 768 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); |
720 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ReflectedXSS)) { | 769 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ReflectedXSS)) { |
721 parseReflectedXSS(name, value); | 770 parseReflectedXSS(name, value); |
722 } else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer)) { | 771 } else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer)) { |
723 parseReferrer(name, value); | 772 parseReferrer(name, value); |
773 } else if (RuntimeEnabledFeatures::suboriginsEnabled() && equalIgnoringCase( name, ContentSecurityPolicy::Suborigin)) { | |
774 applySuboriginPolicy(name, value); | |
724 } else if (m_policy->experimentalFeaturesEnabled()) { | 775 } else if (m_policy->experimentalFeaturesEnabled()) { |
725 if (equalIgnoringCase(name, ContentSecurityPolicy::ManifestSrc)) | 776 if (equalIgnoringCase(name, ContentSecurityPolicy::ManifestSrc)) |
726 setCSPDirective<SourceListDirective>(name, value, m_manifestSrc); | 777 setCSPDirective<SourceListDirective>(name, value, m_manifestSrc); |
727 else if (equalIgnoringCase(name, ContentSecurityPolicy::BlockAllMixedCon tent)) | 778 else if (equalIgnoringCase(name, ContentSecurityPolicy::BlockAllMixedCon tent)) |
728 enforceStrictMixedContentChecking(name, value); | 779 enforceStrictMixedContentChecking(name, value); |
729 else if (equalIgnoringCase(name, ContentSecurityPolicy::UpgradeInsecureR equests)) | 780 else if (equalIgnoringCase(name, ContentSecurityPolicy::UpgradeInsecureR equests)) |
730 enableInsecureRequestsUpgrade(name, value); | 781 enableInsecureRequestsUpgrade(name, value); |
731 else | 782 else |
732 m_policy->reportUnsupportedDirective(name); | 783 m_policy->reportUnsupportedDirective(name); |
733 } else { | 784 } else { |
734 m_policy->reportUnsupportedDirective(name); | 785 m_policy->reportUnsupportedDirective(name); |
735 } | 786 } |
736 } | 787 } |
737 | 788 |
738 | 789 |
739 } // namespace blink | 790 } // namespace blink |
OLD | NEW |