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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 #include "platform/weborigin/KnownPorts.h" | 55 #include "platform/weborigin/KnownPorts.h" |
56 #include "platform/weborigin/SchemeRegistry.h" | 56 #include "platform/weborigin/SchemeRegistry.h" |
57 #include "platform/weborigin/SecurityOrigin.h" | 57 #include "platform/weborigin/SecurityOrigin.h" |
58 #include "public/platform/Platform.h" | 58 #include "public/platform/Platform.h" |
59 #include "wtf/StringHasher.h" | 59 #include "wtf/StringHasher.h" |
60 #include "wtf/text/StringBuilder.h" | 60 #include "wtf/text/StringBuilder.h" |
61 #include "wtf/text/StringUTF8Adaptor.h" | 61 #include "wtf/text/StringUTF8Adaptor.h" |
62 | 62 |
63 namespace blink { | 63 namespace blink { |
64 | 64 |
65 // CSP 1.0 Directives | 65 // CSP Level 1 Directives |
66 const char ContentSecurityPolicy::ConnectSrc[] = "connect-src"; | 66 const char ContentSecurityPolicy::ConnectSrc[] = "connect-src"; |
67 const char ContentSecurityPolicy::DefaultSrc[] = "default-src"; | 67 const char ContentSecurityPolicy::DefaultSrc[] = "default-src"; |
68 const char ContentSecurityPolicy::FontSrc[] = "font-src"; | 68 const char ContentSecurityPolicy::FontSrc[] = "font-src"; |
69 const char ContentSecurityPolicy::FrameSrc[] = "frame-src"; | 69 const char ContentSecurityPolicy::FrameSrc[] = "frame-src"; |
70 const char ContentSecurityPolicy::ImgSrc[] = "img-src"; | 70 const char ContentSecurityPolicy::ImgSrc[] = "img-src"; |
71 const char ContentSecurityPolicy::MediaSrc[] = "media-src"; | 71 const char ContentSecurityPolicy::MediaSrc[] = "media-src"; |
72 const char ContentSecurityPolicy::ObjectSrc[] = "object-src"; | 72 const char ContentSecurityPolicy::ObjectSrc[] = "object-src"; |
73 const char ContentSecurityPolicy::ReportURI[] = "report-uri"; | 73 const char ContentSecurityPolicy::ReportURI[] = "report-uri"; |
74 const char ContentSecurityPolicy::Sandbox[] = "sandbox"; | 74 const char ContentSecurityPolicy::Sandbox[] = "sandbox"; |
75 const char ContentSecurityPolicy::ScriptSrc[] = "script-src"; | 75 const char ContentSecurityPolicy::ScriptSrc[] = "script-src"; |
76 const char ContentSecurityPolicy::StyleSrc[] = "style-src"; | 76 const char ContentSecurityPolicy::StyleSrc[] = "style-src"; |
77 | 77 |
78 // CSP 1.1 Directives | 78 // CSP Level 2 Directives |
79 const char ContentSecurityPolicy::BaseURI[] = "base-uri"; | 79 const char ContentSecurityPolicy::BaseURI[] = "base-uri"; |
80 const char ContentSecurityPolicy::ChildSrc[] = "child-src"; | 80 const char ContentSecurityPolicy::ChildSrc[] = "child-src"; |
81 const char ContentSecurityPolicy::FormAction[] = "form-action"; | 81 const char ContentSecurityPolicy::FormAction[] = "form-action"; |
82 const char ContentSecurityPolicy::FrameAncestors[] = "frame-ancestors"; | 82 const char ContentSecurityPolicy::FrameAncestors[] = "frame-ancestors"; |
83 const char ContentSecurityPolicy::PluginTypes[] = "plugin-types"; | 83 const char ContentSecurityPolicy::PluginTypes[] = "plugin-types"; |
84 const char ContentSecurityPolicy::ReflectedXSS[] = "reflected-xss"; | 84 const char ContentSecurityPolicy::ReflectedXSS[] = "reflected-xss"; |
85 const char ContentSecurityPolicy::Referrer[] = "referrer"; | 85 const char ContentSecurityPolicy::Referrer[] = "referrer"; |
86 | 86 |
87 // Manifest Directives | 87 // Manifest Directives |
88 // https://w3c.github.io/manifest/#content-security-policy | 88 // https://w3c.github.io/manifest/#content-security-policy |
89 const char ContentSecurityPolicy::ManifestSrc[] = "manifest-src"; | 89 const char ContentSecurityPolicy::ManifestSrc[] = "manifest-src"; |
90 | 90 |
| 91 // Mixed Content Directive |
| 92 // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode |
| 93 const char ContentSecurityPolicy::StrictMixedContentChecking[] = "strict-mixed-c
ontent-checking"; |
| 94 |
91 bool ContentSecurityPolicy::isDirectiveName(const String& name) | 95 bool ContentSecurityPolicy::isDirectiveName(const String& name) |
92 { | 96 { |
93 return (equalIgnoringCase(name, ConnectSrc) | 97 return (equalIgnoringCase(name, ConnectSrc) |
94 || equalIgnoringCase(name, DefaultSrc) | 98 || equalIgnoringCase(name, DefaultSrc) |
95 || equalIgnoringCase(name, FontSrc) | 99 || equalIgnoringCase(name, FontSrc) |
96 || equalIgnoringCase(name, FrameSrc) | 100 || equalIgnoringCase(name, FrameSrc) |
97 || equalIgnoringCase(name, ImgSrc) | 101 || equalIgnoringCase(name, ImgSrc) |
98 || equalIgnoringCase(name, MediaSrc) | 102 || equalIgnoringCase(name, MediaSrc) |
99 || equalIgnoringCase(name, ObjectSrc) | 103 || equalIgnoringCase(name, ObjectSrc) |
100 || equalIgnoringCase(name, ReportURI) | 104 || equalIgnoringCase(name, ReportURI) |
101 || equalIgnoringCase(name, Sandbox) | 105 || equalIgnoringCase(name, Sandbox) |
102 || equalIgnoringCase(name, ScriptSrc) | 106 || equalIgnoringCase(name, ScriptSrc) |
103 || equalIgnoringCase(name, StyleSrc) | 107 || equalIgnoringCase(name, StyleSrc) |
104 || equalIgnoringCase(name, BaseURI) | 108 || equalIgnoringCase(name, BaseURI) |
105 || equalIgnoringCase(name, ChildSrc) | 109 || equalIgnoringCase(name, ChildSrc) |
106 || equalIgnoringCase(name, FormAction) | 110 || equalIgnoringCase(name, FormAction) |
107 || equalIgnoringCase(name, FrameAncestors) | 111 || equalIgnoringCase(name, FrameAncestors) |
108 || equalIgnoringCase(name, PluginTypes) | 112 || equalIgnoringCase(name, PluginTypes) |
109 || equalIgnoringCase(name, ReflectedXSS) | 113 || equalIgnoringCase(name, ReflectedXSS) |
110 || equalIgnoringCase(name, Referrer) | 114 || equalIgnoringCase(name, Referrer) |
111 || equalIgnoringCase(name, ManifestSrc) | 115 || equalIgnoringCase(name, ManifestSrc) |
112 ); | 116 || equalIgnoringCase(name, StrictMixedContentChecking)); |
113 } | 117 } |
114 | 118 |
115 static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType typ
e) | 119 static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType typ
e) |
116 { | 120 { |
117 switch (type) { | 121 switch (type) { |
118 case ContentSecurityPolicyHeaderTypeEnforce: | 122 case ContentSecurityPolicyHeaderTypeEnforce: |
119 return UseCounter::ContentSecurityPolicy; | 123 return UseCounter::ContentSecurityPolicy; |
120 case ContentSecurityPolicyHeaderTypeReport: | 124 case ContentSecurityPolicyHeaderTypeReport: |
121 return UseCounter::ContentSecurityPolicyReportOnly; | 125 return UseCounter::ContentSecurityPolicyReportOnly; |
122 } | 126 } |
123 ASSERT_NOT_REACHED(); | 127 ASSERT_NOT_REACHED(); |
124 return UseCounter::NumberOfFeatures; | 128 return UseCounter::NumberOfFeatures; |
125 } | 129 } |
126 | 130 |
127 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) | 131 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) |
128 { | 132 { |
129 if (a != b) | 133 if (a != b) |
130 return ReferrerPolicyNever; | 134 return ReferrerPolicyNever; |
131 return a; | 135 return a; |
132 } | 136 } |
133 | 137 |
134 ContentSecurityPolicy::ContentSecurityPolicy() | 138 ContentSecurityPolicy::ContentSecurityPolicy() |
135 : m_executionContext(nullptr) | 139 : m_executionContext(nullptr) |
136 , m_overrideInlineStyleAllowed(false) | 140 , m_overrideInlineStyleAllowed(false) |
137 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) | 141 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) |
138 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) | 142 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) |
139 , m_sandboxMask(0) | 143 , m_sandboxMask(0) |
| 144 , m_enforceStrictMixedContentChecking(false) |
140 , m_referrerPolicy(ReferrerPolicyDefault) | 145 , m_referrerPolicy(ReferrerPolicyDefault) |
141 { | 146 { |
142 } | 147 } |
143 | 148 |
144 void ContentSecurityPolicy::bindToExecutionContext(ExecutionContext* executionCo
ntext) | 149 void ContentSecurityPolicy::bindToExecutionContext(ExecutionContext* executionCo
ntext) |
145 { | 150 { |
146 m_executionContext = executionContext; | 151 m_executionContext = executionContext; |
147 applyPolicySideEffectsToExecutionContext(); | 152 applyPolicySideEffectsToExecutionContext(); |
148 } | 153 } |
149 | 154 |
150 void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext() | 155 void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext() |
151 { | 156 { |
152 ASSERT(m_executionContext); | 157 ASSERT(m_executionContext); |
153 // Ensure that 'self' processes correctly. | 158 // Ensure that 'self' processes correctly. |
154 m_selfProtocol = securityOrigin()->protocol(); | 159 m_selfProtocol = securityOrigin()->protocol(); |
155 m_selfSource = adoptPtr(new CSPSource(this, m_selfProtocol, securityOrigin()
->host(), securityOrigin()->port(), String(), CSPSource::NoWildcard, CSPSource::
NoWildcard)); | 160 m_selfSource = adoptPtr(new CSPSource(this, m_selfProtocol, securityOrigin()
->host(), securityOrigin()->port(), String(), CSPSource::NoWildcard, CSPSource::
NoWildcard)); |
156 | 161 |
157 // If we're in a Document, set the referrer policy and sandbox flags, then d
ump all the | 162 // If we're in a Document, set the referrer policy, mixed content checking,
and sandbox |
158 // parsing error messages, then poke at histograms. | 163 // flags, then dump all the parsing error messages, then poke at histograms. |
159 if (Document* document = this->document()) { | 164 if (Document* document = this->document()) { |
160 document->enforceSandboxFlags(m_sandboxMask); | 165 document->enforceSandboxFlags(m_sandboxMask); |
| 166 if (m_enforceStrictMixedContentChecking) |
| 167 document->enforceStrictMixedContentChecking(); |
161 if (didSetReferrerPolicy()) | 168 if (didSetReferrerPolicy()) |
162 document->setReferrerPolicy(m_referrerPolicy); | 169 document->setReferrerPolicy(m_referrerPolicy); |
163 | 170 |
164 for (const auto& consoleMessage : m_consoleMessages) | 171 for (const auto& consoleMessage : m_consoleMessages) |
165 m_executionContext->addConsoleMessage(consoleMessage); | 172 m_executionContext->addConsoleMessage(consoleMessage); |
166 m_consoleMessages.clear(); | 173 m_consoleMessages.clear(); |
167 | 174 |
168 for (const auto& policy : m_policies) | 175 for (const auto& policy : m_policies) |
169 UseCounter::count(*document, getUseCounterType(policy->headerType())
); | 176 UseCounter::count(*document, getUseCounterType(policy->headerType())
); |
170 } | 177 } |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 KURL ContentSecurityPolicy::completeURL(const String& url) const | 599 KURL ContentSecurityPolicy::completeURL(const String& url) const |
593 { | 600 { |
594 return m_executionContext->contextCompleteURL(url); | 601 return m_executionContext->contextCompleteURL(url); |
595 } | 602 } |
596 | 603 |
597 void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) | 604 void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) |
598 { | 605 { |
599 m_sandboxMask |= mask; | 606 m_sandboxMask |= mask; |
600 } | 607 } |
601 | 608 |
| 609 void ContentSecurityPolicy::enforceStrictMixedContentChecking() |
| 610 { |
| 611 m_enforceStrictMixedContentChecking = true; |
| 612 } |
| 613 |
602 static String stripURLForUseInReport(Document* document, const KURL& url) | 614 static String stripURLForUseInReport(Document* document, const KURL& url) |
603 { | 615 { |
604 if (!url.isValid()) | 616 if (!url.isValid()) |
605 return String(); | 617 return String(); |
606 if (!url.isHierarchical() || url.protocolIs("file")) | 618 if (!url.isHierarchical() || url.protocolIs("file")) |
607 return url.protocol(); | 619 return url.protocol(); |
608 return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsRef
errer() : SecurityOrigin::create(url)->toString(); | 620 return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsRef
errer() : SecurityOrigin::create(url)->toString(); |
609 } | 621 } |
610 | 622 |
611 static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
nit& init, Document* document, const String& directiveText, const String& effect
iveDirective, const KURL& blockedURL, const String& header) | 623 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 Loading... |
721 void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) | 733 void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) |
722 { | 734 { |
723 logToConsole("The report-only Content Security Policy '" + header + "' was d
elivered via a <meta> element, which is disallowed. The policy has been ignored.
"); | 735 logToConsole("The report-only Content Security Policy '" + header + "' was d
elivered via a <meta> element, which is disallowed. The policy has been ignored.
"); |
724 } | 736 } |
725 | 737 |
726 void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) | 738 void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) |
727 { | 739 { |
728 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."); | 740 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."); |
729 } | 741 } |
730 | 742 |
| 743 void ContentSecurityPolicy::reportValueForEmptyDirective(const String& name, con
st String& value) |
| 744 { |
| 745 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."); |
| 746 } |
| 747 |
731 void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) | 748 void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) |
732 { | 749 { |
733 logToConsole("The Content Security Policy directive '" + name + "' is ignore
d when delivered in a report-only policy."); | 750 logToConsole("The Content Security Policy directive '" + name + "' is ignore
d when delivered in a report-only policy."); |
734 } | 751 } |
735 | 752 |
736 void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) | 753 void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) |
737 { | 754 { |
738 DEFINE_STATIC_LOCAL(String, allow, ("allow")); | 755 DEFINE_STATIC_LOCAL(String, allow, ("allow")); |
739 DEFINE_STATIC_LOCAL(String, options, ("options")); | 756 DEFINE_STATIC_LOCAL(String, options, ("options")); |
740 DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri")); | 757 DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri")); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. | 889 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. |
873 return !m_violationReportsSent.contains(report.impl()->hash()); | 890 return !m_violationReportsSent.contains(report.impl()->hash()); |
874 } | 891 } |
875 | 892 |
876 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 893 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
877 { | 894 { |
878 m_violationReportsSent.add(report.impl()->hash()); | 895 m_violationReportsSent.add(report.impl()->hash()); |
879 } | 896 } |
880 | 897 |
881 } // namespace blink | 898 } // namespace blink |
OLD | NEW |