| 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 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 } | 565 } |
| 565 directive = adoptPtr(new CSPDirectiveType(name, value, m_policy)); | 566 directive = adoptPtr(new CSPDirectiveType(name, value, m_policy)); |
| 566 } | 567 } |
| 567 | 568 |
| 568 void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sand
boxPolicy) | 569 void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sand
boxPolicy) |
| 569 { | 570 { |
| 570 if (m_reportOnly) { | 571 if (m_reportOnly) { |
| 571 m_policy->reportInvalidInReportOnly(name); | 572 m_policy->reportInvalidInReportOnly(name); |
| 572 return; | 573 return; |
| 573 } | 574 } |
| 574 if (m_haveSandboxPolicy) { | 575 if (m_hasSandboxPolicy) { |
| 575 m_policy->reportDuplicateDirective(name); | 576 m_policy->reportDuplicateDirective(name); |
| 576 return; | 577 return; |
| 577 } | 578 } |
| 578 m_haveSandboxPolicy = true; | 579 m_hasSandboxPolicy = true; |
| 579 String invalidTokens; | 580 String invalidTokens; |
| 580 m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidToken
s)); | 581 m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidToken
s)); |
| 581 if (!invalidTokens.isNull()) | 582 if (!invalidTokens.isNull()) |
| 582 m_policy->reportInvalidSandboxFlags(invalidTokens); | 583 m_policy->reportInvalidSandboxFlags(invalidTokens); |
| 583 } | 584 } |
| 584 | 585 |
| 585 void CSPDirectiveList::enforceStrictMixedContentChecking(const String& name, con
st String& value) | 586 void CSPDirectiveList::enforceStrictMixedContentChecking(const String& name, con
st String& value) |
| 586 { | 587 { |
| 587 if (m_reportOnly) { | 588 if (m_reportOnly) { |
| 588 m_policy->reportInvalidInReportOnly(name); | 589 m_policy->reportInvalidInReportOnly(name); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 608 m_policy->reportDuplicateDirective(name); | 609 m_policy->reportDuplicateDirective(name); |
| 609 return; | 610 return; |
| 610 } | 611 } |
| 611 m_upgradeInsecureRequests = true; | 612 m_upgradeInsecureRequests = true; |
| 612 | 613 |
| 613 m_policy->setInsecureRequestsPolicy(SecurityContext::InsecureRequestsUpgrade
); | 614 m_policy->setInsecureRequestsPolicy(SecurityContext::InsecureRequestsUpgrade
); |
| 614 if (!value.isEmpty()) | 615 if (!value.isEmpty()) |
| 615 m_policy->reportValueForEmptyDirective(name, value); | 616 m_policy->reportValueForEmptyDirective(name, value); |
| 616 } | 617 } |
| 617 | 618 |
| 619 void CSPDirectiveList::applySuboriginPolicy(const String& name, const String& su
boriginPolicy) |
| 620 { |
| 621 ASSERT(RuntimeEnabledFeatures::suboriginsEnabled()); |
| 622 if (m_headerSource == ContentSecurityPolicyHeaderSourceMeta) { |
| 623 m_policy->reportSuboriginInMeta(suboriginPolicy); |
| 624 return; |
| 625 } |
| 626 |
| 627 if (m_hasSuboriginPolicy) { |
| 628 m_policy->reportDuplicateDirective(name); |
| 629 return; |
| 630 } |
| 631 m_hasSuboriginPolicy = true; |
| 632 String suboriginName = parseSuboriginName(suboriginPolicy); |
| 633 if (!suboriginName.isNull()) |
| 634 m_policy->enforceSuborigin(suboriginName); |
| 635 } |
| 636 |
| 618 void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value
) | 637 void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value
) |
| 619 { | 638 { |
| 620 if (m_reflectedXSSDisposition != ReflectedXSSUnset) { | 639 if (m_reflectedXSSDisposition != ReflectedXSSUnset) { |
| 621 m_policy->reportDuplicateDirective(name); | 640 m_policy->reportDuplicateDirective(name); |
| 622 m_reflectedXSSDisposition = ReflectedXSSInvalid; | 641 m_reflectedXSSDisposition = ReflectedXSSInvalid; |
| 623 return; | 642 return; |
| 624 } | 643 } |
| 625 | 644 |
| 626 if (value.isEmpty()) { | 645 if (value.isEmpty()) { |
| 627 m_reflectedXSSDisposition = ReflectedXSSInvalid; | 646 m_reflectedXSSDisposition = ReflectedXSSInvalid; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 skipWhile<UChar, isASCIISpace>(position, end); | 728 skipWhile<UChar, isASCIISpace>(position, end); |
| 710 if (position == end) | 729 if (position == end) |
| 711 return; | 730 return; |
| 712 | 731 |
| 713 // value1 value2 | 732 // value1 value2 |
| 714 // ^ | 733 // ^ |
| 715 m_referrerPolicy = ReferrerPolicyNever; | 734 m_referrerPolicy = ReferrerPolicyNever; |
| 716 m_policy->reportInvalidReferrer(value); | 735 m_policy->reportInvalidReferrer(value); |
| 717 } | 736 } |
| 718 | 737 |
| 738 String CSPDirectiveList::parseSuboriginName(const String& policy) |
| 739 { |
| 740 Vector<UChar> characters; |
| 741 policy.appendTo(characters); |
| 742 |
| 743 const UChar* position = characters.data(); |
| 744 const UChar* end = position + characters.size(); |
| 745 |
| 746 // Parse the name of the suborigin (no spaces, single string) |
| 747 skipWhile<UChar, isASCIISpace>(position, end); |
| 748 if (position == end) { |
| 749 m_policy->reportInvalidSuboriginFlags("No suborigin name specified."); |
| 750 return String(); |
| 751 } |
| 752 |
| 753 const UChar* begin = position; |
| 754 |
| 755 skipWhile<UChar, isASCIIAlphanumeric>(position, end); |
| 756 if (position != end && !isASCIISpace(*position)) { |
| 757 m_policy->reportInvalidSuboriginFlags("Invalid character \'" + String(po
sition, 1) + "\' in suborigin."); |
| 758 return String(); |
| 759 } |
| 760 size_t length = position - begin; |
| 761 skipWhile<UChar, isASCIISpace>(position, end); |
| 762 if (position != end) { |
| 763 m_policy->reportInvalidSuboriginFlags("Whitespace is not allowed in subo
rigin names."); |
| 764 return String(); |
| 765 } |
| 766 |
| 767 return String(begin, length); |
| 768 } |
| 769 |
| 719 void CSPDirectiveList::addDirective(const String& name, const String& value) | 770 void CSPDirectiveList::addDirective(const String& name, const String& value) |
| 720 { | 771 { |
| 721 ASSERT(!name.isEmpty()); | 772 ASSERT(!name.isEmpty()); |
| 722 | 773 |
| 723 if (equalIgnoringCase(name, ContentSecurityPolicy::DefaultSrc)) { | 774 if (equalIgnoringCase(name, ContentSecurityPolicy::DefaultSrc)) { |
| 724 setCSPDirective<SourceListDirective>(name, value, m_defaultSrc); | 775 setCSPDirective<SourceListDirective>(name, value, m_defaultSrc); |
| 725 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ScriptSrc)) { | 776 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ScriptSrc)) { |
| 726 setCSPDirective<SourceListDirective>(name, value, m_scriptSrc); | 777 setCSPDirective<SourceListDirective>(name, value, m_scriptSrc); |
| 727 m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed()); | 778 m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed()); |
| 728 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ObjectSrc)) { | 779 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ObjectSrc)) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 753 } else if (equalIgnoringCase(name, ContentSecurityPolicy::FormAction)) { | 804 } else if (equalIgnoringCase(name, ContentSecurityPolicy::FormAction)) { |
| 754 setCSPDirective<SourceListDirective>(name, value, m_formAction); | 805 setCSPDirective<SourceListDirective>(name, value, m_formAction); |
| 755 } else if (equalIgnoringCase(name, ContentSecurityPolicy::PluginTypes)) { | 806 } else if (equalIgnoringCase(name, ContentSecurityPolicy::PluginTypes)) { |
| 756 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); | 807 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); |
| 757 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ReflectedXSS)) { | 808 } else if (equalIgnoringCase(name, ContentSecurityPolicy::ReflectedXSS)) { |
| 758 parseReflectedXSS(name, value); | 809 parseReflectedXSS(name, value); |
| 759 } else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer)) { | 810 } else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer)) { |
| 760 parseReferrer(name, value); | 811 parseReferrer(name, value); |
| 761 } else if (equalIgnoringCase(name, ContentSecurityPolicy::UpgradeInsecureReq
uests)) { | 812 } else if (equalIgnoringCase(name, ContentSecurityPolicy::UpgradeInsecureReq
uests)) { |
| 762 enableInsecureRequestsUpgrade(name, value); | 813 enableInsecureRequestsUpgrade(name, value); |
| 814 } else if (RuntimeEnabledFeatures::suboriginsEnabled() && equalIgnoringCase(
name, ContentSecurityPolicy::Suborigin)) { |
| 815 applySuboriginPolicy(name, value); |
| 763 } else if (m_policy->experimentalFeaturesEnabled()) { | 816 } else if (m_policy->experimentalFeaturesEnabled()) { |
| 764 if (equalIgnoringCase(name, ContentSecurityPolicy::ManifestSrc)) | 817 if (equalIgnoringCase(name, ContentSecurityPolicy::ManifestSrc)) |
| 765 setCSPDirective<SourceListDirective>(name, value, m_manifestSrc); | 818 setCSPDirective<SourceListDirective>(name, value, m_manifestSrc); |
| 766 else if (equalIgnoringCase(name, ContentSecurityPolicy::BlockAllMixedCon
tent)) | 819 else if (equalIgnoringCase(name, ContentSecurityPolicy::BlockAllMixedCon
tent)) |
| 767 enforceStrictMixedContentChecking(name, value); | 820 enforceStrictMixedContentChecking(name, value); |
| 768 else | 821 else |
| 769 m_policy->reportUnsupportedDirective(name); | 822 m_policy->reportUnsupportedDirective(name); |
| 770 } else { | 823 } else { |
| 771 m_policy->reportUnsupportedDirective(name); | 824 m_policy->reportUnsupportedDirective(name); |
| 772 } | 825 } |
| 773 } | 826 } |
| 774 | 827 |
| 775 | 828 |
| 776 } // namespace blink | 829 } // namespace blink |
| OLD | NEW |