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 20 matching lines...) Expand all Loading... |
31 #include "bindings/v8/ScriptController.h" | 31 #include "bindings/v8/ScriptController.h" |
32 #include "core/dom/DOMStringList.h" | 32 #include "core/dom/DOMStringList.h" |
33 #include "core/dom/Document.h" | 33 #include "core/dom/Document.h" |
34 #include "core/events/SecurityPolicyViolationEvent.h" | 34 #include "core/events/SecurityPolicyViolationEvent.h" |
35 #include "core/frame/ContentSecurityPolicyResponseHeaders.h" | 35 #include "core/frame/ContentSecurityPolicyResponseHeaders.h" |
36 #include "core/frame/DOMWindow.h" | 36 #include "core/frame/DOMWindow.h" |
37 #include "core/frame/LocalFrame.h" | 37 #include "core/frame/LocalFrame.h" |
38 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
39 #include "core/frame/csp/CSPSource.h" | 39 #include "core/frame/csp/CSPSource.h" |
40 #include "core/frame/csp/CSPSourceList.h" | 40 #include "core/frame/csp/CSPSourceList.h" |
| 41 #include "core/frame/csp/MediaListDirective.h" |
| 42 #include "core/frame/csp/SourceListDirective.h" |
41 #include "core/inspector/InspectorInstrumentation.h" | 43 #include "core/inspector/InspectorInstrumentation.h" |
42 #include "core/inspector/ScriptCallStack.h" | 44 #include "core/inspector/ScriptCallStack.h" |
43 #include "core/loader/DocumentLoader.h" | 45 #include "core/loader/DocumentLoader.h" |
44 #include "core/loader/PingLoader.h" | 46 #include "core/loader/PingLoader.h" |
45 #include "platform/JSONValues.h" | 47 #include "platform/JSONValues.h" |
46 #include "platform/NotImplemented.h" | 48 #include "platform/NotImplemented.h" |
47 #include "platform/ParsingUtilities.h" | 49 #include "platform/ParsingUtilities.h" |
48 #include "platform/network/ContentSecurityPolicyParsers.h" | 50 #include "platform/network/ContentSecurityPolicyParsers.h" |
49 #include "platform/network/FormData.h" | 51 #include "platform/network/FormData.h" |
50 #include "platform/network/ResourceResponse.h" | 52 #include "platform/network/ResourceResponse.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 return UseCounter::NumberOfFeatures; | 121 return UseCounter::NumberOfFeatures; |
120 } | 122 } |
121 | 123 |
122 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) | 124 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) |
123 { | 125 { |
124 if (a != b) | 126 if (a != b) |
125 return ReferrerPolicyNever; | 127 return ReferrerPolicyNever; |
126 return a; | 128 return a; |
127 } | 129 } |
128 | 130 |
129 class CSPDirective { | |
130 public: | |
131 CSPDirective(const String& name, const String& value, ContentSecurityPolicy*
policy) | |
132 : m_name(name) | |
133 , m_text(name + ' ' + value) | |
134 , m_policy(policy) | |
135 { | |
136 } | |
137 | |
138 const String& text() const { return m_text; } | |
139 | |
140 protected: | |
141 const ContentSecurityPolicy* policy() const { return m_policy; } | |
142 | |
143 private: | |
144 String m_name; | |
145 String m_text; | |
146 ContentSecurityPolicy* m_policy; | |
147 }; | |
148 | |
149 class MediaListDirective : public CSPDirective { | |
150 public: | |
151 MediaListDirective(const String& name, const String& value, ContentSecurityP
olicy* policy) | |
152 : CSPDirective(name, value, policy) | |
153 { | |
154 Vector<UChar> characters; | |
155 value.appendTo(characters); | |
156 parse(characters.data(), characters.data() + characters.size()); | |
157 } | |
158 | |
159 bool allows(const String& type) | |
160 { | |
161 return m_pluginTypes.contains(type); | |
162 } | |
163 | |
164 private: | |
165 void parse(const UChar* begin, const UChar* end) | |
166 { | |
167 const UChar* position = begin; | |
168 | |
169 // 'plugin-types ____;' OR 'plugin-types;' | |
170 if (position == end) { | |
171 policy()->reportInvalidPluginTypes(String()); | |
172 return; | |
173 } | |
174 | |
175 while (position < end) { | |
176 // _____ OR _____mime1/mime1 | |
177 // ^ ^ | |
178 skipWhile<UChar, isASCIISpace>(position, end); | |
179 if (position == end) | |
180 return; | |
181 | |
182 // mime1/mime1 mime2/mime2 | |
183 // ^ | |
184 begin = position; | |
185 if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) { | |
186 skipWhile<UChar, isNotASCIISpace>(position, end); | |
187 policy()->reportInvalidPluginTypes(String(begin, position - begi
n)); | |
188 continue; | |
189 } | |
190 skipWhile<UChar, isMediaTypeCharacter>(position, end); | |
191 | |
192 // mime1/mime1 mime2/mime2 | |
193 // ^ | |
194 if (!skipExactly<UChar>(position, end, '/')) { | |
195 skipWhile<UChar, isNotASCIISpace>(position, end); | |
196 policy()->reportInvalidPluginTypes(String(begin, position - begi
n)); | |
197 continue; | |
198 } | |
199 | |
200 // mime1/mime1 mime2/mime2 | |
201 // ^ | |
202 if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) { | |
203 skipWhile<UChar, isNotASCIISpace>(position, end); | |
204 policy()->reportInvalidPluginTypes(String(begin, position - begi
n)); | |
205 continue; | |
206 } | |
207 skipWhile<UChar, isMediaTypeCharacter>(position, end); | |
208 | |
209 // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error | |
210 // ^ ^ ^ | |
211 if (position < end && isNotASCIISpace(*position)) { | |
212 skipWhile<UChar, isNotASCIISpace>(position, end); | |
213 policy()->reportInvalidPluginTypes(String(begin, position - begi
n)); | |
214 continue; | |
215 } | |
216 m_pluginTypes.add(String(begin, position - begin)); | |
217 | |
218 ASSERT(position == end || isASCIISpace(*position)); | |
219 } | |
220 } | |
221 | |
222 HashSet<String> m_pluginTypes; | |
223 }; | |
224 | |
225 class SourceListDirective : public CSPDirective { | |
226 public: | |
227 SourceListDirective(const String& name, const String& value, ContentSecurity
Policy* policy) | |
228 : CSPDirective(name, value, policy) | |
229 , m_sourceList(policy, name) | |
230 { | |
231 Vector<UChar> characters; | |
232 value.appendTo(characters); | |
233 | |
234 m_sourceList.parse(characters.data(), characters.data() + characters.siz
e()); | |
235 } | |
236 | |
237 bool allows(const KURL& url) | |
238 { | |
239 return m_sourceList.matches(url.isEmpty() ? policy()->url() : url); | |
240 } | |
241 | |
242 bool allowInline() const { return m_sourceList.allowInline(); } | |
243 bool allowEval() const { return m_sourceList.allowEval(); } | |
244 bool allowNonce(const String& nonce) const { return m_sourceList.allowNonce(
nonce.stripWhiteSpace()); } | |
245 bool allowHash(const CSPHashValue& hashValue) const { return m_sourceList.al
lowHash(hashValue); } | |
246 bool isHashOrNoncePresent() const { return m_sourceList.isHashOrNoncePresent
(); } | |
247 | |
248 uint8_t hashAlgorithmsUsed() const { return m_sourceList.hashAlgorithmsUsed(
); } | |
249 | |
250 private: | |
251 CSPSourceList m_sourceList; | |
252 }; | |
253 | |
254 class CSPDirectiveList { | 131 class CSPDirectiveList { |
255 WTF_MAKE_FAST_ALLOCATED; | 132 WTF_MAKE_FAST_ALLOCATED; |
256 public: | 133 public: |
257 static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UCh
ar* begin, const UChar* end, ContentSecurityPolicy::HeaderType, ContentSecurityP
olicy::HeaderSource); | 134 static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UCh
ar* begin, const UChar* end, ContentSecurityPolicy::HeaderType, ContentSecurityP
olicy::HeaderSource); |
258 | 135 |
259 void parse(const UChar* begin, const UChar* end); | 136 void parse(const UChar* begin, const UChar* end); |
260 | 137 |
261 const String& header() const { return m_header; } | 138 const String& header() const { return m_header; } |
262 ContentSecurityPolicy::HeaderType headerType() const { return m_headerType;
} | 139 ContentSecurityPolicy::HeaderType headerType() const { return m_headerType;
} |
263 ContentSecurityPolicy::HeaderSource headerSource() const { return m_headerSo
urce; } | 140 ContentSecurityPolicy::HeaderSource headerSource() const { return m_headerSo
urce; } |
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1684 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. | 1561 // Collisions have no security impact, so we can save space by storing only
the string's hash rather than the whole report. |
1685 return !m_violationReportsSent.contains(report.impl()->hash()); | 1562 return !m_violationReportsSent.contains(report.impl()->hash()); |
1686 } | 1563 } |
1687 | 1564 |
1688 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 1565 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
1689 { | 1566 { |
1690 m_violationReportsSent.add(report.impl()->hash()); | 1567 m_violationReportsSent.add(report.impl()->hash()); |
1691 } | 1568 } |
1692 | 1569 |
1693 } // namespace WebCore | 1570 } // namespace WebCore |
OLD | NEW |