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

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

Issue 1109633002: Basic experimental suborigin CSP directive and SecurityOrigin mods (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 // https://w3c.github.io/manifest/#content-security-policy 91 // https://w3c.github.io/manifest/#content-security-policy
92 const char ContentSecurityPolicy::ManifestSrc[] = "manifest-src"; 92 const char ContentSecurityPolicy::ManifestSrc[] = "manifest-src";
93 93
94 // Mixed Content Directive 94 // Mixed Content Directive
95 // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode 95 // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode
96 const char ContentSecurityPolicy::BlockAllMixedContent[] = "block-all-mixed-cont ent"; 96 const char ContentSecurityPolicy::BlockAllMixedContent[] = "block-all-mixed-cont ent";
97 97
98 // https://w3c.github.io/webappsec/specs/upgrade/ 98 // https://w3c.github.io/webappsec/specs/upgrade/
99 const char ContentSecurityPolicy::UpgradeInsecureRequests[] = "upgrade-insecure- requests"; 99 const char ContentSecurityPolicy::UpgradeInsecureRequests[] = "upgrade-insecure- requests";
100 100
101 // Suborigin Directive
102 // https://metromoxie.github.io/webappsec/specs/suborigins/index.html
103 const char ContentSecurityPolicy::Suborigin[] = "suborigin";
104
101 bool ContentSecurityPolicy::isDirectiveName(const String& name) 105 bool ContentSecurityPolicy::isDirectiveName(const String& name)
102 { 106 {
103 return (equalIgnoringCase(name, ConnectSrc) 107 return (equalIgnoringCase(name, ConnectSrc)
104 || equalIgnoringCase(name, DefaultSrc) 108 || equalIgnoringCase(name, DefaultSrc)
105 || equalIgnoringCase(name, FontSrc) 109 || equalIgnoringCase(name, FontSrc)
106 || equalIgnoringCase(name, FrameSrc) 110 || equalIgnoringCase(name, FrameSrc)
107 || equalIgnoringCase(name, ImgSrc) 111 || equalIgnoringCase(name, ImgSrc)
108 || equalIgnoringCase(name, MediaSrc) 112 || equalIgnoringCase(name, MediaSrc)
109 || equalIgnoringCase(name, ObjectSrc) 113 || equalIgnoringCase(name, ObjectSrc)
110 || equalIgnoringCase(name, ReportURI) 114 || equalIgnoringCase(name, ReportURI)
111 || equalIgnoringCase(name, Sandbox) 115 || equalIgnoringCase(name, Sandbox)
116 || equalIgnoringCase(name, Suborigin)
112 || equalIgnoringCase(name, ScriptSrc) 117 || equalIgnoringCase(name, ScriptSrc)
113 || equalIgnoringCase(name, StyleSrc) 118 || equalIgnoringCase(name, StyleSrc)
114 || equalIgnoringCase(name, BaseURI) 119 || equalIgnoringCase(name, BaseURI)
115 || equalIgnoringCase(name, ChildSrc) 120 || equalIgnoringCase(name, ChildSrc)
116 || equalIgnoringCase(name, FormAction) 121 || equalIgnoringCase(name, FormAction)
117 || equalIgnoringCase(name, FrameAncestors) 122 || equalIgnoringCase(name, FrameAncestors)
118 || equalIgnoringCase(name, PluginTypes) 123 || equalIgnoringCase(name, PluginTypes)
119 || equalIgnoringCase(name, ReflectedXSS) 124 || equalIgnoringCase(name, ReflectedXSS)
120 || equalIgnoringCase(name, Referrer) 125 || equalIgnoringCase(name, Referrer)
121 || equalIgnoringCase(name, ManifestSrc) 126 || equalIgnoringCase(name, ManifestSrc)
(...skipping 19 matching lines...) Expand all
141 return ReferrerPolicyNever; 146 return ReferrerPolicyNever;
142 return a; 147 return a;
143 } 148 }
144 149
145 ContentSecurityPolicy::ContentSecurityPolicy() 150 ContentSecurityPolicy::ContentSecurityPolicy()
146 : m_executionContext(nullptr) 151 : m_executionContext(nullptr)
147 , m_overrideInlineStyleAllowed(false) 152 , m_overrideInlineStyleAllowed(false)
148 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) 153 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone)
149 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) 154 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone)
150 , m_sandboxMask(0) 155 , m_sandboxMask(0)
156 , m_suboriginName(String())
151 , m_enforceStrictMixedContentChecking(false) 157 , m_enforceStrictMixedContentChecking(false)
152 , m_referrerPolicy(ReferrerPolicyDefault) 158 , m_referrerPolicy(ReferrerPolicyDefault)
153 , m_insecureRequestsPolicy(SecurityContext::InsecureRequestsDoNotUpgrade) 159 , m_insecureRequestsPolicy(SecurityContext::InsecureRequestsDoNotUpgrade)
154 { 160 {
155 } 161 }
156 162
157 void ContentSecurityPolicy::bindToExecutionContext(ExecutionContext* executionCo ntext) 163 void ContentSecurityPolicy::bindToExecutionContext(ExecutionContext* executionCo ntext)
158 { 164 {
159 m_executionContext = executionContext; 165 m_executionContext = executionContext;
160 applyPolicySideEffectsToExecutionContext(); 166 applyPolicySideEffectsToExecutionContext();
161 } 167 }
162 168
163 void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext() 169 void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext()
164 { 170 {
165 ASSERT(m_executionContext); 171 ASSERT(m_executionContext);
166 ASSERT(securityOrigin()); 172 ASSERT(securityOrigin());
167 // Ensure that 'self' processes correctly. 173 // Ensure that 'self' processes correctly.
168 m_selfProtocol = securityOrigin()->protocol(); 174 m_selfProtocol = securityOrigin()->protocol();
169 m_selfSource = adoptPtr(new CSPSource(this, m_selfProtocol, securityOrigin() ->host(), securityOrigin()->port(), String(), CSPSource::NoWildcard, CSPSource:: NoWildcard)); 175 m_selfSource = adoptPtr(new CSPSource(this, m_selfProtocol, securityOrigin() ->host(), securityOrigin()->port(), String(), CSPSource::NoWildcard, CSPSource:: NoWildcard));
170 176
171 // If we're in a Document, set the referrer policy, mixed content checking, and sandbox 177 // If we're in a Document, set the referrer policy, mixed content checking, and sandbox
172 // flags, then dump all the parsing error messages, then poke at histograms. 178 // flags, then dump all the parsing error messages, then poke at histograms.
173 if (Document* document = this->document()) { 179 if (Document* document = this->document()) {
174 if (m_sandboxMask != SandboxNone) { 180 if (m_sandboxMask != SandboxNone) {
175 UseCounter::count(document, UseCounter::SandboxViaCSP); 181 UseCounter::count(document, UseCounter::SandboxViaCSP);
176 document->enforceSandboxFlags(m_sandboxMask); 182 document->enforceSandboxFlags(m_sandboxMask);
177 } 183 }
178 if (m_enforceStrictMixedContentChecking) 184 if (m_enforceStrictMixedContentChecking)
179 document->enforceStrictMixedContentChecking(); 185 document->enforceStrictMixedContentChecking();
186 if (RuntimeEnabledFeatures::suboriginsEnabled()) {
187 document->enforceSuborigin(m_suboriginName);
188 }
180 if (didSetReferrerPolicy()) 189 if (didSetReferrerPolicy())
181 document->setReferrerPolicy(m_referrerPolicy); 190 document->setReferrerPolicy(m_referrerPolicy);
182 if (m_insecureRequestsPolicy == SecurityContext::InsecureRequestsUpgrade ) { 191 if (m_insecureRequestsPolicy == SecurityContext::InsecureRequestsUpgrade ) {
183 UseCounter::count(document, UseCounter::UpgradeInsecureRequestsEnabl ed); 192 UseCounter::count(document, UseCounter::UpgradeInsecureRequestsEnabl ed);
184 document->setInsecureRequestsPolicy(m_insecureRequestsPolicy); 193 document->setInsecureRequestsPolicy(m_insecureRequestsPolicy);
185 if (!securityOrigin()->host().isNull()) 194 if (!securityOrigin()->host().isNull())
186 document->addInsecureNavigationUpgrade(securityOrigin()->host(). impl()->hash()); 195 document->addInsecureNavigationUpgrade(securityOrigin()->host(). impl()->hash());
187 } 196 }
188 197
189 for (const auto& consoleMessage : m_consoleMessages) 198 for (const auto& consoleMessage : m_consoleMessages)
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 { 656 {
648 m_enforceStrictMixedContentChecking = true; 657 m_enforceStrictMixedContentChecking = true;
649 } 658 }
650 659
651 void ContentSecurityPolicy::setInsecureRequestsPolicy(SecurityContext::InsecureR equestsPolicy policy) 660 void ContentSecurityPolicy::setInsecureRequestsPolicy(SecurityContext::InsecureR equestsPolicy policy)
652 { 661 {
653 if (policy > m_insecureRequestsPolicy) 662 if (policy > m_insecureRequestsPolicy)
654 m_insecureRequestsPolicy = policy; 663 m_insecureRequestsPolicy = policy;
655 } 664 }
656 665
666 void ContentSecurityPolicy::enforceSuborigin(const String& name)
667 {
668 m_suboriginName = name;
669 }
670
657 static String stripURLForUseInReport(Document* document, const KURL& url) 671 static String stripURLForUseInReport(Document* document, const KURL& url)
658 { 672 {
659 if (!url.isValid()) 673 if (!url.isValid())
660 return String(); 674 return String();
661 if (!url.isHierarchical() || url.protocolIs("file")) 675 if (!url.isHierarchical() || url.protocolIs("file"))
662 return url.protocol(); 676 return url.protocol();
663 return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsRef errer() : SecurityOrigin::create(url)->toString(); 677 return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsRef errer() : SecurityOrigin::create(url)->toString();
664 } 678 }
665 679
666 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI nit& init, Document* document, const String& directiveText, const String& effect iveDirective, const KURL& blockedURL, const String& header) 680 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI nit& init, Document* document, const String& directiveText, const String& effect iveDirective, const KURL& blockedURL, const String& header)
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) 790 void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header)
777 { 791 {
778 logToConsole("The report-only Content Security Policy '" + header + "' was d elivered via a <meta> element, which is disallowed. The policy has been ignored. "); 792 logToConsole("The report-only Content Security Policy '" + header + "' was d elivered via a <meta> element, which is disallowed. The policy has been ignored. ");
779 } 793 }
780 794
781 void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) 795 void ContentSecurityPolicy::reportMetaOutsideHead(const String& header)
782 { 796 {
783 logToConsole("The Content Security Policy '" + header + "' was delivered via a <meta> element outside the document's <head>, which is disallowed. The policy has been ignored."); 797 logToConsole("The Content Security Policy '" + header + "' was delivered via a <meta> element outside the document's <head>, which is disallowed. The policy has been ignored.");
784 } 798 }
785 799
800 void ContentSecurityPolicy::reportSuboriginInMeta(const String& suboriginName)
801 {
802 logToConsole("The Suborigin name '" + suboriginName + "' was delivered via a Content Security Policy in a <meta> element and not an HTTP header, which is di sallowed. The Suborigin has been ignored.");
803 }
804
786 void ContentSecurityPolicy::reportValueForEmptyDirective(const String& name, con st String& value) 805 void ContentSecurityPolicy::reportValueForEmptyDirective(const String& name, con st String& value)
787 { 806 {
788 logToConsole("The Content Security Policy directive '" + name + "' should be empty, but was delivered with a value of '" + value + "'. The directive has bee n applied, and the value ignored."); 807 logToConsole("The Content Security Policy directive '" + name + "' should be empty, but was delivered with a value of '" + value + "'. The directive has bee n applied, and the value ignored.");
789 } 808 }
790 809
791 void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) 810 void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name)
792 { 811 {
793 logToConsole("The Content Security Policy directive '" + name + "' is ignore d when delivered in a report-only policy."); 812 logToConsole("The Content Security Policy directive '" + name + "' is ignore d when delivered in a report-only policy.");
794 } 813 }
795 814
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 else 859 else
841 message = "Invalid plugin type in 'plugin-types' Content Security Policy directive: '" + pluginType + "'.\n"; 860 message = "Invalid plugin type in 'plugin-types' Content Security Policy directive: '" + pluginType + "'.\n";
842 logToConsole(message); 861 logToConsole(message);
843 } 862 }
844 863
845 void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags ) 864 void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags )
846 { 865 {
847 logToConsole("Error while parsing the 'sandbox' Content Security Policy dire ctive: " + invalidFlags); 866 logToConsole("Error while parsing the 'sandbox' Content Security Policy dire ctive: " + invalidFlags);
848 } 867 }
849 868
869 void ContentSecurityPolicy::reportInvalidSuboriginFlags(const String& invalidFla gs)
870 {
871 logToConsole("Error while parsing the 'suborigin' Content Security Policy di rective: " + invalidFlags);
872 }
873
850 void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue ) 874 void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue )
851 { 875 {
852 logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\"."); 876 logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\".");
853 } 877 }
854 878
855 void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& d irectiveName, const String& value) 879 void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& d irectiveName, const String& value)
856 { 880 {
857 String message = "The value for Content Security Policy directive '" + direc tiveName + "' contains an invalid character: '" + value + "'. Non-whitespace cha racters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 398 6, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1."; 881 String message = "The value for Content Security Policy directive '" + direc tiveName + "' contains an invalid character: '" + value + "'. Non-whitespace cha racters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 398 6, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.";
858 logToConsole(message); 882 logToConsole(message);
859 } 883 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. 992 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report.
969 return !m_violationReportsSent.contains(report.impl()->hash()); 993 return !m_violationReportsSent.contains(report.impl()->hash());
970 } 994 }
971 995
972 void ContentSecurityPolicy::didSendViolationReport(const String& report) 996 void ContentSecurityPolicy::didSendViolationReport(const String& report)
973 { 997 {
974 m_violationReportsSent.add(report.impl()->hash()); 998 m_violationReportsSent.add(report.impl()->hash());
975 } 999 }
976 1000
977 } // namespace blink 1001 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698