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 17 matching lines...) Expand all Loading... | |
28 | 28 |
29 #include "RuntimeEnabledFeatures.h" | 29 #include "RuntimeEnabledFeatures.h" |
30 #include "bindings/v8/ScriptCallStackFactory.h" | 30 #include "bindings/v8/ScriptCallStackFactory.h" |
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/DOMWindow.h" | 35 #include "core/frame/DOMWindow.h" |
36 #include "core/frame/LocalFrame.h" | 36 #include "core/frame/LocalFrame.h" |
37 #include "core/frame/UseCounter.h" | 37 #include "core/frame/UseCounter.h" |
38 #include "core/frame/csp/CSPDirectiveList.h" | |
38 #include "core/frame/csp/CSPSource.h" | 39 #include "core/frame/csp/CSPSource.h" |
39 #include "core/frame/csp/CSPSourceList.h" | 40 #include "core/frame/csp/CSPSourceList.h" |
40 #include "core/frame/csp/MediaListDirective.h" | 41 #include "core/frame/csp/MediaListDirective.h" |
41 #include "core/frame/csp/SourceListDirective.h" | 42 #include "core/frame/csp/SourceListDirective.h" |
42 #include "core/inspector/InspectorInstrumentation.h" | 43 #include "core/inspector/InspectorInstrumentation.h" |
43 #include "core/inspector/ScriptCallStack.h" | 44 #include "core/inspector/ScriptCallStack.h" |
44 #include "core/loader/DocumentLoader.h" | 45 #include "core/loader/DocumentLoader.h" |
45 #include "core/loader/PingLoader.h" | 46 #include "core/loader/PingLoader.h" |
46 #include "platform/JSONValues.h" | 47 #include "platform/JSONValues.h" |
47 #include "platform/NotImplemented.h" | 48 #include "platform/NotImplemented.h" |
(...skipping 10 matching lines...) Expand all Loading... | |
58 #include "public/platform/WebArrayBuffer.h" | 59 #include "public/platform/WebArrayBuffer.h" |
59 #include "public/platform/WebCrypto.h" | 60 #include "public/platform/WebCrypto.h" |
60 #include "public/platform/WebCryptoAlgorithm.h" | 61 #include "public/platform/WebCryptoAlgorithm.h" |
61 #include "wtf/HashMap.h" | 62 #include "wtf/HashMap.h" |
62 #include "wtf/StringHasher.h" | 63 #include "wtf/StringHasher.h" |
63 #include "wtf/text/StringBuilder.h" | 64 #include "wtf/text/StringBuilder.h" |
64 | 65 |
65 namespace WebCore { | 66 namespace WebCore { |
66 | 67 |
67 // CSP 1.0 Directives | 68 // CSP 1.0 Directives |
68 static const char connectSrc[] = "connect-src"; | 69 const char ContentSecurityPolicy::ConnectSrc[] = "connect-src"; |
69 static const char defaultSrc[] = "default-src"; | 70 const char ContentSecurityPolicy::DefaultSrc[] = "default-src"; |
70 static const char fontSrc[] = "font-src"; | 71 const char ContentSecurityPolicy::FontSrc[] = "font-src"; |
71 static const char frameSrc[] = "frame-src"; | 72 const char ContentSecurityPolicy::FrameSrc[] = "frame-src"; |
72 static const char imgSrc[] = "img-src"; | 73 const char ContentSecurityPolicy::ImgSrc[] = "img-src"; |
73 static const char mediaSrc[] = "media-src"; | 74 const char ContentSecurityPolicy::MediaSrc[] = "media-src"; |
74 static const char objectSrc[] = "object-src"; | 75 const char ContentSecurityPolicy::ObjectSrc[] = "object-src"; |
75 static const char reportURI[] = "report-uri"; | 76 const char ContentSecurityPolicy::ReportURI[] = "report-uri"; |
76 static const char sandbox[] = "sandbox"; | 77 const char ContentSecurityPolicy::Sandbox[] = "sandbox"; |
77 static const char scriptSrc[] = "script-src"; | 78 const char ContentSecurityPolicy::ScriptSrc[] = "script-src"; |
78 static const char styleSrc[] = "style-src"; | 79 const char ContentSecurityPolicy::StyleSrc[] = "style-src"; |
79 | 80 |
80 // CSP 1.1 Directives | 81 // CSP 1.1 Directives |
81 static const char baseURI[] = "base-uri"; | 82 const char ContentSecurityPolicy::BaseURI[] = "base-uri"; |
82 static const char childSrc[] = "child-src"; | 83 const char ContentSecurityPolicy::ChildSrc[] = "child-src"; |
83 static const char formAction[] = "form-action"; | 84 const char ContentSecurityPolicy::FormAction[] = "form-action"; |
84 static const char frameAncestors[] = "frame-ancestors"; | 85 const char ContentSecurityPolicy::FrameAncestors[] = "frame-ancestors"; |
85 static const char pluginTypes[] = "plugin-types"; | 86 const char ContentSecurityPolicy::PluginTypes[] = "plugin-types"; |
86 static const char reflectedXSS[] = "reflected-xss"; | 87 const char ContentSecurityPolicy::ReflectedXSS[] = "reflected-xss"; |
87 static const char referrer[] = "referrer"; | 88 const char ContentSecurityPolicy::Referrer[] = "referrer"; |
88 | 89 |
89 bool ContentSecurityPolicy::isDirectiveName(const String& name) | 90 bool ContentSecurityPolicy::isDirectiveName(const String& name) |
90 { | 91 { |
91 return (equalIgnoringCase(name, connectSrc) | 92 return (equalIgnoringCase(name, ConnectSrc) |
92 || equalIgnoringCase(name, defaultSrc) | 93 || equalIgnoringCase(name, DefaultSrc) |
kenneth.r.christiansen
2014/03/04 10:45:24
We are getting quite many here... :-) I was wonder
| |
93 || equalIgnoringCase(name, fontSrc) | 94 || equalIgnoringCase(name, FontSrc) |
94 || equalIgnoringCase(name, frameSrc) | 95 || equalIgnoringCase(name, FrameSrc) |
95 || equalIgnoringCase(name, imgSrc) | 96 || equalIgnoringCase(name, ImgSrc) |
96 || equalIgnoringCase(name, mediaSrc) | 97 || equalIgnoringCase(name, MediaSrc) |
97 || equalIgnoringCase(name, objectSrc) | 98 || equalIgnoringCase(name, ObjectSrc) |
98 || equalIgnoringCase(name, reportURI) | 99 || equalIgnoringCase(name, ReportURI) |
99 || equalIgnoringCase(name, sandbox) | 100 || equalIgnoringCase(name, Sandbox) |
100 || equalIgnoringCase(name, scriptSrc) | 101 || equalIgnoringCase(name, ScriptSrc) |
101 || equalIgnoringCase(name, styleSrc) | 102 || equalIgnoringCase(name, StyleSrc) |
102 || equalIgnoringCase(name, baseURI) | 103 || equalIgnoringCase(name, BaseURI) |
103 || equalIgnoringCase(name, childSrc) | 104 || equalIgnoringCase(name, ChildSrc) |
104 || equalIgnoringCase(name, formAction) | 105 || equalIgnoringCase(name, FormAction) |
105 || equalIgnoringCase(name, frameAncestors) | 106 || equalIgnoringCase(name, FrameAncestors) |
106 || equalIgnoringCase(name, pluginTypes) | 107 || equalIgnoringCase(name, PluginTypes) |
107 || equalIgnoringCase(name, reflectedXSS) | 108 || equalIgnoringCase(name, ReflectedXSS) |
108 || equalIgnoringCase(name, referrer) | 109 || equalIgnoringCase(name, Referrer) |
109 ); | 110 ); |
110 } | 111 } |
111 | 112 |
112 static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType typ e) | 113 static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType typ e) |
113 { | 114 { |
114 switch (type) { | 115 switch (type) { |
115 case ContentSecurityPolicyHeaderTypeEnforce: | 116 case ContentSecurityPolicyHeaderTypeEnforce: |
116 return UseCounter::ContentSecurityPolicy; | 117 return UseCounter::ContentSecurityPolicy; |
117 case ContentSecurityPolicyHeaderTypeReport: | 118 case ContentSecurityPolicyHeaderTypeReport: |
118 return UseCounter::ContentSecurityPolicyReportOnly; | 119 return UseCounter::ContentSecurityPolicyReportOnly; |
119 } | 120 } |
120 ASSERT_NOT_REACHED(); | 121 ASSERT_NOT_REACHED(); |
121 return UseCounter::NumberOfFeatures; | 122 return UseCounter::NumberOfFeatures; |
122 } | 123 } |
123 | 124 |
124 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) | 125 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) |
125 { | 126 { |
126 if (a != b) | 127 if (a != b) |
127 return ReferrerPolicyNever; | 128 return ReferrerPolicyNever; |
128 return a; | 129 return a; |
129 } | 130 } |
130 | 131 |
131 class CSPDirectiveList { | |
132 WTF_MAKE_FAST_ALLOCATED; | |
133 public: | |
134 static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UCh ar* begin, const UChar* end, ContentSecurityPolicyHeaderType, ContentSecurityPol icyHeaderSource); | |
135 | |
136 void parse(const UChar* begin, const UChar* end); | |
137 | |
138 const String& header() const { return m_header; } | |
139 ContentSecurityPolicyHeaderType headerType() const { return m_headerType; } | |
140 ContentSecurityPolicyHeaderSource headerSource() const { return m_headerSour ce; } | |
141 | |
142 bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; | |
143 bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNu mber& contextLine, ContentSecurityPolicy::ReportingStatus) const; | |
144 bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& c ontextLine, ContentSecurityPolicy::ReportingStatus) const; | |
145 bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& co ntextLine, ContentSecurityPolicy::ReportingStatus) const; | |
146 bool allowEval(ScriptState*, ContentSecurityPolicy::ReportingStatus) const; | |
147 bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ContentSecurityPolicy::ReportingStatus) const; | |
148 | |
149 bool allowScriptFromSource(const KURL&, ContentSecurityPolicy::ReportingStat us) const; | |
150 bool allowObjectFromSource(const KURL&, ContentSecurityPolicy::ReportingStat us) const; | |
151 bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::Reporting Status) const; | |
152 bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; | |
153 bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; | |
154 bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus ) const; | |
155 bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; | |
156 bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatu s) const; | |
157 bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) co nst; | |
158 bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const ; | |
159 bool allowAncestors(LocalFrame*, ContentSecurityPolicy::ReportingStatus) con st; | |
160 bool allowChildContextFromSource(const KURL&, ContentSecurityPolicy::Reporti ngStatus) const; | |
161 bool allowScriptNonce(const String&) const; | |
162 bool allowStyleNonce(const String&) const; | |
163 bool allowScriptHash(const CSPHashValue&) const; | |
164 bool allowStyleHash(const CSPHashValue&) const; | |
165 | |
166 const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorM essage; } | |
167 ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflected XSSDisposition; } | |
168 ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; } | |
169 bool didSetReferrerPolicy() const { return m_didSetReferrerPolicy; } | |
170 bool isReportOnly() const { return m_reportOnly; } | |
171 const Vector<KURL>& reportURIs() const { return m_reportURIs; } | |
172 | |
173 private: | |
174 CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicyHeaderType, Co ntentSecurityPolicyHeaderSource); | |
175 | |
176 bool parseDirective(const UChar* begin, const UChar* end, String& name, Stri ng& value); | |
177 void parseReportURI(const String& name, const String& value); | |
178 void parsePluginTypes(const String& name, const String& value); | |
179 void parseReflectedXSS(const String& name, const String& value); | |
180 void parseReferrer(const String& name, const String& value); | |
181 void addDirective(const String& name, const String& value); | |
182 void applySandboxPolicy(const String& name, const String& sandboxPolicy); | |
183 | |
184 template <class CSPDirectiveType> | |
185 void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDire ctiveType>&); | |
186 | |
187 SourceListDirective* operativeDirective(SourceListDirective*) const; | |
188 SourceListDirective* operativeDirective(SourceListDirective*, SourceListDire ctive* override) const; | |
189 void reportViolation(const String& directiveText, const String& effectiveDir ective, const String& consoleMessage, const KURL& blockedURL) const; | |
190 void reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const; | |
191 void reportViolationWithState(const String& directiveText, const String& eff ectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptSta te*) const; | |
192 | |
193 bool checkEval(SourceListDirective*) const; | |
194 bool checkInline(SourceListDirective*) const; | |
195 bool checkNonce(SourceListDirective*, const String&) const; | |
196 bool checkHash(SourceListDirective*, const CSPHashValue&) const; | |
197 bool checkSource(SourceListDirective*, const KURL&) const; | |
198 bool checkMediaType(MediaListDirective*, const String& type, const String& t ypeAttribute) const; | |
199 bool checkAncestors(SourceListDirective*, LocalFrame*) const; | |
200 | |
201 void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisable dErrorMessage = errorMessage; } | |
202 | |
203 bool checkEvalAndReportViolation(SourceListDirective*, const String& console Message, ScriptState*) const; | |
204 bool checkInlineAndReportViolation(SourceListDirective*, const String& conso leMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const; | |
205 | |
206 bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const; | |
207 bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& typ e, const String& typeAttribute, const String& consoleMessage) const; | |
208 bool checkAncestorsAndReportViolation(SourceListDirective*, LocalFrame*) con st; | |
209 | |
210 bool denyIfEnforcingPolicy() const { return m_reportOnly; } | |
211 | |
212 ContentSecurityPolicy* m_policy; | |
213 | |
214 String m_header; | |
215 ContentSecurityPolicyHeaderType m_headerType; | |
216 ContentSecurityPolicyHeaderSource m_headerSource; | |
217 | |
218 bool m_reportOnly; | |
219 bool m_haveSandboxPolicy; | |
220 ReflectedXSSDisposition m_reflectedXSSDisposition; | |
221 | |
222 bool m_didSetReferrerPolicy; | |
223 ReferrerPolicy m_referrerPolicy; | |
224 | |
225 OwnPtr<MediaListDirective> m_pluginTypes; | |
226 OwnPtr<SourceListDirective> m_baseURI; | |
227 OwnPtr<SourceListDirective> m_childSrc; | |
228 OwnPtr<SourceListDirective> m_connectSrc; | |
229 OwnPtr<SourceListDirective> m_defaultSrc; | |
230 OwnPtr<SourceListDirective> m_fontSrc; | |
231 OwnPtr<SourceListDirective> m_formAction; | |
232 OwnPtr<SourceListDirective> m_frameAncestors; | |
233 OwnPtr<SourceListDirective> m_frameSrc; | |
234 OwnPtr<SourceListDirective> m_imgSrc; | |
235 OwnPtr<SourceListDirective> m_mediaSrc; | |
236 OwnPtr<SourceListDirective> m_objectSrc; | |
237 OwnPtr<SourceListDirective> m_scriptSrc; | |
238 OwnPtr<SourceListDirective> m_styleSrc; | |
239 | |
240 Vector<KURL> m_reportURIs; | |
241 | |
242 String m_evalDisabledErrorMessage; | |
243 }; | |
244 | |
245 CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurit yPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) | |
246 : m_policy(policy) | |
247 , m_headerType(type) | |
248 , m_headerSource(source) | |
249 , m_reportOnly(false) | |
250 , m_haveSandboxPolicy(false) | |
251 , m_reflectedXSSDisposition(ReflectedXSSUnset) | |
252 , m_didSetReferrerPolicy(false) | |
253 , m_referrerPolicy(ReferrerPolicyDefault) | |
254 { | |
255 m_reportOnly = type == ContentSecurityPolicyHeaderTypeReport; | |
256 } | |
257 | |
258 PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* pol icy, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) | |
259 { | |
260 OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type, source)); | |
261 directives->parse(begin, end); | |
262 | |
263 if (!directives->checkEval(directives->operativeDirective(directives->m_scri ptSrc.get()))) { | |
264 String message = "Refused to evaluate a string as JavaScript because 'un safe-eval' is not an allowed source of script in the following Content Security Policy directive: \"" + directives->operativeDirective(directives->m_scriptSrc.g et())->text() + "\".\n"; | |
265 directives->setEvalDisabledErrorMessage(message); | |
266 } | |
267 | |
268 if (directives->isReportOnly() && directives->reportURIs().isEmpty()) | |
269 policy->reportMissingReportURI(String(begin, end - begin)); | |
270 | |
271 return directives.release(); | |
272 } | |
273 | |
274 void CSPDirectiveList::reportViolation(const String& directiveText, const String & effectiveDirective, const String& consoleMessage, const KURL& blockedURL) cons t | |
275 { | |
276 String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleM essage; | |
277 m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLev el, message); | |
278 m_policy->reportViolation(directiveText, effectiveDirective, message, blocke dURL, m_reportURIs, m_header); | |
279 } | |
280 | |
281 void CSPDirectiveList::reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& bloc kedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const | |
282 { | |
283 String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleM essage; | |
284 m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLev el, message, contextURL, contextLine.oneBasedInt()); | |
285 m_policy->reportViolation(directiveText, effectiveDirective, message, blocke dURL, m_reportURIs, m_header); | |
286 } | |
287 | |
288 void CSPDirectiveList::reportViolationWithState(const String& directiveText, con st String& effectiveDirective, const String& consoleMessage, const KURL& blocked URL, ScriptState* state) const | |
289 { | |
290 String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleM essage; | |
291 m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLev el, message, state); | |
292 m_policy->reportViolation(directiveText, effectiveDirective, message, blocke dURL, m_reportURIs, m_header); | |
293 } | |
294 | |
295 bool CSPDirectiveList::checkEval(SourceListDirective* directive) const | |
296 { | |
297 return !directive || directive->allowEval(); | |
298 } | |
299 | |
300 bool CSPDirectiveList::checkInline(SourceListDirective* directive) const | |
301 { | |
302 return !directive || (directive->allowInline() && !directive->isHashOrNonceP resent()); | |
303 } | |
304 | |
305 bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const | |
306 { | |
307 return !directive || directive->allowNonce(nonce); | |
308 } | |
309 | |
310 bool CSPDirectiveList::checkHash(SourceListDirective* directive, const CSPHashVa lue& hashValue) const | |
311 { | |
312 return !directive || directive->allowHash(hashValue); | |
313 } | |
314 | |
315 bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& u rl) const | |
316 { | |
317 return !directive || directive->allows(url); | |
318 } | |
319 | |
320 bool CSPDirectiveList::checkAncestors(SourceListDirective* directive, LocalFrame * frame) const | |
321 { | |
322 if (!frame || !directive) | |
323 return true; | |
324 | |
325 for (LocalFrame* current = frame->tree().parent(); current; current = curren t->tree().parent()) { | |
326 if (!directive->allows(current->document()->url())) | |
327 return false; | |
328 } | |
329 return true; | |
330 } | |
331 | |
332 bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const Strin g& type, const String& typeAttribute) const | |
333 { | |
334 if (!directive) | |
335 return true; | |
336 if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type) | |
337 return false; | |
338 return directive->allows(type); | |
339 } | |
340 | |
341 SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* d irective) const | |
342 { | |
343 return directive ? directive : m_defaultSrc.get(); | |
344 } | |
345 | |
346 SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* d irective, SourceListDirective* override) const | |
347 { | |
348 return directive ? directive : override; | |
349 } | |
350 | |
351 bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directiv e, const String& consoleMessage, ScriptState* state) const | |
352 { | |
353 if (checkEval(directive)) | |
354 return true; | |
355 | |
356 String suffix = String(); | |
357 if (directive == m_defaultSrc) | |
358 suffix = " Note that 'script-src' was not explicitly set, so 'default-sr c' is used as a fallback."; | |
359 | |
360 reportViolationWithState(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), state); | |
361 if (!m_reportOnly) { | |
362 m_policy->reportBlockedScriptExecutionToInspector(directive->text()); | |
363 return false; | |
364 } | |
365 return true; | |
366 } | |
367 | |
368 bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* dire ctive, const String& type, const String& typeAttribute, const String& consoleMes sage) const | |
369 { | |
370 if (checkMediaType(directive, type, typeAttribute)) | |
371 return true; | |
372 | |
373 String message = consoleMessage + "\'" + directive->text() + "\'."; | |
374 if (typeAttribute.isEmpty()) | |
375 message = message + " When enforcing the 'plugin-types' directive, the p lugin's media type must be explicitly declared with a 'type' attribute on the co ntaining element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>')."; | |
376 | |
377 reportViolation(directive->text(), pluginTypes, message + "\n", KURL()); | |
378 return denyIfEnforcingPolicy(); | |
379 } | |
380 | |
381 bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* direct ive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalN umber& contextLine, bool isScript) const | |
382 { | |
383 if (checkInline(directive)) | |
384 return true; | |
385 | |
386 String suffix = String(); | |
387 if (directive->allowInline() && directive->isHashOrNoncePresent()) { | |
388 // If inline is allowed, but a hash or nonce is present, we ignore 'unsa fe-inline'. Throw a reasonable error. | |
389 suffix = " Note that 'unsafe-inline' is ignored if either a hash or nonc e value is present in the source list."; | |
390 } else { | |
391 suffix = " Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution."; | |
392 if (directive == m_defaultSrc) | |
393 suffix = suffix + " Note also that '" + String(isScript ? "script" : "style") + "-src' was not explicitly set, so 'default-src' is used as a fallbac k."; | |
394 } | |
395 | |
396 reportViolationWithLocation(directive->text(), isScript ? scriptSrc : styleS rc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), c ontextURL, contextLine); | |
397 | |
398 if (!m_reportOnly) { | |
399 if (isScript) | |
400 m_policy->reportBlockedScriptExecutionToInspector(directive->text()) ; | |
401 return false; | |
402 } | |
403 return true; | |
404 } | |
405 | |
406 bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* direct ive, const KURL& url, const String& effectiveDirective) const | |
407 { | |
408 if (checkSource(directive, url)) | |
409 return true; | |
410 | |
411 String prefix; | |
412 if (baseURI == effectiveDirective) | |
413 prefix = "Refused to set the document's base URI to '"; | |
414 else if (childSrc == effectiveDirective) | |
415 prefix = "Refused to create a child context containing '"; | |
416 else if (connectSrc == effectiveDirective) | |
417 prefix = "Refused to connect to '"; | |
418 else if (fontSrc == effectiveDirective) | |
419 prefix = "Refused to load the font '"; | |
420 else if (formAction == effectiveDirective) | |
421 prefix = "Refused to send form data to '"; | |
422 else if (frameSrc == effectiveDirective) | |
423 prefix = "Refused to frame '"; | |
424 else if (imgSrc == effectiveDirective) | |
425 prefix = "Refused to load the image '"; | |
426 else if (mediaSrc == effectiveDirective) | |
427 prefix = "Refused to load media from '"; | |
428 else if (objectSrc == effectiveDirective) | |
429 prefix = "Refused to load plugin data from '"; | |
430 else if (scriptSrc == effectiveDirective) | |
431 prefix = "Refused to load the script '"; | |
432 else if (styleSrc == effectiveDirective) | |
433 prefix = "Refused to load the stylesheet '"; | |
434 | |
435 String suffix = String(); | |
436 if (directive == m_defaultSrc) | |
437 suffix = " Note that '" + effectiveDirective + "' was not explicitly set , so 'default-src' is used as a fallback."; | |
438 | |
439 reportViolation(directive->text(), effectiveDirective, prefix + url.elidedSt ring() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url); | |
440 return denyIfEnforcingPolicy(); | |
441 } | |
442 | |
443 bool CSPDirectiveList::checkAncestorsAndReportViolation(SourceListDirective* dir ective, LocalFrame* frame) const | |
444 { | |
445 if (checkAncestors(directive, frame)) | |
446 return true; | |
447 | |
448 reportViolation(directive->text(), "frame-ancestors", "Refused to display '" + frame->document()->url().elidedString() + " in a frame because an ancestor vi olates the following Content Security Policy directive: \"" + directive->text() + "\".", frame->document()->url()); | |
449 return denyIfEnforcingPolicy(); | |
450 } | |
451 | |
452 bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF:: OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStat us) const | |
453 { | |
454 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: ")); | |
455 if (reportingStatus == ContentSecurityPolicy::SendReport) | |
456 return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get( )), consoleMessage, contextURL, contextLine, true); | |
457 | |
458 return checkInline(operativeDirective(m_scriptSrc.get())); | |
459 } | |
460 | |
461 bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportin gStatus) const | |
462 { | |
463 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline even t handler because it violates the following Content Security Policy directive: " )); | |
464 if (reportingStatus == ContentSecurityPolicy::SendReport) | |
465 return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get( )), consoleMessage, contextURL, contextLine, true); | |
466 return checkInline(operativeDirective(m_scriptSrc.get())); | |
467 } | |
468 | |
469 bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::Or dinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus ) const | |
470 { | |
471 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline scri pt because it violates the following Content Security Policy directive: ")); | |
472 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
473 checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), con soleMessage, contextURL, contextLine, true) : | |
474 checkInline(operativeDirective(m_scriptSrc.get())); | |
475 } | |
476 | |
477 bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::Ord inalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const | |
478 { | |
479 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to apply inline style because it violates the following Content Security Policy directive: ")); | |
480 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
481 checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), cons oleMessage, contextURL, contextLine, false) : | |
482 checkInline(operativeDirective(m_styleSrc.get())); | |
483 } | |
484 | |
485 bool CSPDirectiveList::allowEval(ScriptState* state, ContentSecurityPolicy::Repo rtingStatus reportingStatus) const | |
486 { | |
487 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate a string a s JavaScript because 'unsafe-eval' is not an allowed source of script in the fol lowing Content Security Policy directive: ")); | |
488 | |
489 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
490 checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), conso leMessage, state) : | |
491 checkEval(operativeDirective(m_scriptSrc.get())); | |
492 } | |
493 | |
494 bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAtt ribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const | |
495 { | |
496 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
497 checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribut e, "Refused to load '" + url.elidedString() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") : | |
498 checkMediaType(m_pluginTypes.get(), type, typeAttribute); | |
499 } | |
500 | |
501 bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPol icy::ReportingStatus reportingStatus) const | |
502 { | |
503 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
504 checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url , scriptSrc) : | |
505 checkSource(operativeDirective(m_scriptSrc.get()), url); | |
506 } | |
507 | |
508 bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPol icy::ReportingStatus reportingStatus) const | |
509 { | |
510 if (url.isBlankURL()) | |
511 return true; | |
512 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
513 checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url , objectSrc) : | |
514 checkSource(operativeDirective(m_objectSrc.get()), url); | |
515 } | |
516 | |
517 bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurit yPolicy::ReportingStatus reportingStatus) const | |
518 { | |
519 if (url.isBlankURL()) | |
520 return true; | |
521 | |
522 // 'frame-src' is the only directive which overrides something other than th e default sources. | |
523 // It overrides 'child-src', which overrides the default sources. So, we do this nested set | |
524 // of calls to 'operativeDirective()' to grab 'frame-src' if it exists, 'chi ld-src' if it | |
525 // doesn't, and 'defaut-src' if neither are available. | |
526 // | |
527 // All of this only applies, of course, if we're in CSP 1.1. In CSP 1.0, 'fr ame-src' | |
528 // overrides 'default-src' directly. | |
529 SourceListDirective* whichDirective = m_policy->experimentalFeaturesEnabled( ) ? | |
530 operativeDirective(m_frameSrc.get(), operativeDirective(m_childSrc.get() )) : | |
531 operativeDirective(m_frameSrc.get()); | |
532 | |
533 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
534 checkSourceAndReportViolation(whichDirective, url, frameSrc) : | |
535 checkSource(whichDirective, url); | |
536 } | |
537 | |
538 bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPoli cy::ReportingStatus reportingStatus) const | |
539 { | |
540 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
541 checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, i mgSrc) : | |
542 checkSource(operativeDirective(m_imgSrc.get()), url); | |
543 } | |
544 | |
545 bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPoli cy::ReportingStatus reportingStatus) const | |
546 { | |
547 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
548 checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, styleSrc) : | |
549 checkSource(operativeDirective(m_styleSrc.get()), url); | |
550 } | |
551 | |
552 bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolic y::ReportingStatus reportingStatus) const | |
553 { | |
554 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
555 checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, fontSrc) : | |
556 checkSource(operativeDirective(m_fontSrc.get()), url); | |
557 } | |
558 | |
559 bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPoli cy::ReportingStatus reportingStatus) const | |
560 { | |
561 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
562 checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, mediaSrc) : | |
563 checkSource(operativeDirective(m_mediaSrc.get()), url); | |
564 } | |
565 | |
566 bool CSPDirectiveList::allowConnectToSource(const KURL& url, ContentSecurityPoli cy::ReportingStatus reportingStatus) const | |
567 { | |
568 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
569 checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), ur l, connectSrc) : | |
570 checkSource(operativeDirective(m_connectSrc.get()), url); | |
571 } | |
572 | |
573 bool CSPDirectiveList::allowFormAction(const KURL& url, ContentSecurityPolicy::R eportingStatus reportingStatus) const | |
574 { | |
575 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
576 checkSourceAndReportViolation(m_formAction.get(), url, formAction) : | |
577 checkSource(m_formAction.get(), url); | |
578 } | |
579 | |
580 bool CSPDirectiveList::allowBaseURI(const KURL& url, ContentSecurityPolicy::Repo rtingStatus reportingStatus) const | |
581 { | |
582 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
583 checkSourceAndReportViolation(m_baseURI.get(), url, baseURI) : | |
584 checkSource(m_baseURI.get(), url); | |
585 } | |
586 | |
587 bool CSPDirectiveList::allowAncestors(LocalFrame* frame, ContentSecurityPolicy:: ReportingStatus reportingStatus) const | |
588 { | |
589 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
590 checkAncestorsAndReportViolation(m_frameAncestors.get(), frame) : | |
591 checkAncestors(m_frameAncestors.get(), frame); | |
592 } | |
593 | |
594 bool CSPDirectiveList::allowChildContextFromSource(const KURL& url, ContentSecur ityPolicy::ReportingStatus reportingStatus) const | |
595 { | |
596 return reportingStatus == ContentSecurityPolicy::SendReport ? | |
597 checkSourceAndReportViolation(operativeDirective(m_childSrc.get()), url, childSrc) : | |
598 checkSource(operativeDirective(m_childSrc.get()), url); | |
599 } | |
600 | |
601 bool CSPDirectiveList::allowScriptNonce(const String& nonce) const | |
602 { | |
603 return checkNonce(operativeDirective(m_scriptSrc.get()), nonce); | |
604 } | |
605 | |
606 bool CSPDirectiveList::allowStyleNonce(const String& nonce) const | |
607 { | |
608 return checkNonce(operativeDirective(m_styleSrc.get()), nonce); | |
609 } | |
610 | |
611 bool CSPDirectiveList::allowScriptHash(const CSPHashValue& hashValue) const | |
612 { | |
613 return checkHash(operativeDirective(m_scriptSrc.get()), hashValue); | |
614 } | |
615 | |
616 bool CSPDirectiveList::allowStyleHash(const CSPHashValue& hashValue) const | |
617 { | |
618 return checkHash(operativeDirective(m_styleSrc.get()), hashValue); | |
619 } | |
620 | |
621 // policy = directive-list | |
622 // directive-list = [ directive *( ";" [ directive ] ) ] | |
623 // | |
624 void CSPDirectiveList::parse(const UChar* begin, const UChar* end) | |
625 { | |
626 m_header = String(begin, end - begin); | |
627 | |
628 if (begin == end) | |
629 return; | |
630 | |
631 const UChar* position = begin; | |
632 while (position < end) { | |
633 const UChar* directiveBegin = position; | |
634 skipUntil<UChar>(position, end, ';'); | |
635 | |
636 String name, value; | |
637 if (parseDirective(directiveBegin, position, name, value)) { | |
638 ASSERT(!name.isEmpty()); | |
639 addDirective(name, value); | |
640 } | |
641 | |
642 ASSERT(position == end || *position == ';'); | |
643 skipExactly<UChar>(position, end, ';'); | |
644 } | |
645 } | |
646 | |
647 // directive = *WSP [ directive-name [ WSP directive-value ] ] | |
648 // directive-name = 1*( ALPHA / DIGIT / "-" ) | |
649 // directive-value = *( WSP / <VCHAR except ";"> ) | |
650 // | |
651 bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, Stri ng& name, String& value) | |
652 { | |
653 ASSERT(name.isEmpty()); | |
654 ASSERT(value.isEmpty()); | |
655 | |
656 const UChar* position = begin; | |
657 skipWhile<UChar, isASCIISpace>(position, end); | |
658 | |
659 // Empty directive (e.g. ";;;"). Exit early. | |
660 if (position == end) | |
661 return false; | |
662 | |
663 const UChar* nameBegin = position; | |
664 skipWhile<UChar, isCSPDirectiveNameCharacter>(position, end); | |
665 | |
666 // The directive-name must be non-empty. | |
667 if (nameBegin == position) { | |
668 skipWhile<UChar, isNotASCIISpace>(position, end); | |
669 m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBe gin)); | |
670 return false; | |
671 } | |
672 | |
673 name = String(nameBegin, position - nameBegin); | |
674 | |
675 if (position == end) | |
676 return true; | |
677 | |
678 if (!skipExactly<UChar, isASCIISpace>(position, end)) { | |
679 skipWhile<UChar, isNotASCIISpace>(position, end); | |
680 m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBe gin)); | |
681 return false; | |
682 } | |
683 | |
684 skipWhile<UChar, isASCIISpace>(position, end); | |
685 | |
686 const UChar* valueBegin = position; | |
687 skipWhile<UChar, isCSPDirectiveValueCharacter>(position, end); | |
688 | |
689 if (position != end) { | |
690 m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin)); | |
691 return false; | |
692 } | |
693 | |
694 // The directive-value may be empty. | |
695 if (valueBegin == position) | |
696 return true; | |
697 | |
698 value = String(valueBegin, position - valueBegin); | |
699 return true; | |
700 } | |
701 | |
702 void CSPDirectiveList::parseReportURI(const String& name, const String& value) | |
703 { | |
704 if (!m_reportURIs.isEmpty()) { | |
705 m_policy->reportDuplicateDirective(name); | |
706 return; | |
707 } | |
708 | |
709 Vector<UChar> characters; | |
710 value.appendTo(characters); | |
711 | |
712 const UChar* position = characters.data(); | |
713 const UChar* end = position + characters.size(); | |
714 | |
715 while (position < end) { | |
716 skipWhile<UChar, isASCIISpace>(position, end); | |
717 | |
718 const UChar* urlBegin = position; | |
719 skipWhile<UChar, isNotASCIISpace>(position, end); | |
720 | |
721 if (urlBegin < position) { | |
722 String url = String(urlBegin, position - urlBegin); | |
723 m_reportURIs.append(m_policy->completeURL(url)); | |
724 } | |
725 } | |
726 } | |
727 | |
728 | |
729 template<class CSPDirectiveType> | |
730 void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive) | |
731 { | |
732 if (directive) { | |
733 m_policy->reportDuplicateDirective(name); | |
734 return; | |
735 } | |
736 directive = adoptPtr(new CSPDirectiveType(name, value, m_policy)); | |
737 } | |
738 | |
739 void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sand boxPolicy) | |
740 { | |
741 if (m_reportOnly) { | |
742 m_policy->reportInvalidInReportOnly(name); | |
743 return; | |
744 } | |
745 if (m_haveSandboxPolicy) { | |
746 m_policy->reportDuplicateDirective(name); | |
747 return; | |
748 } | |
749 m_haveSandboxPolicy = true; | |
750 String invalidTokens; | |
751 m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidToken s)); | |
752 if (!invalidTokens.isNull()) | |
753 m_policy->reportInvalidSandboxFlags(invalidTokens); | |
754 } | |
755 | |
756 void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value ) | |
757 { | |
758 if (m_reflectedXSSDisposition != ReflectedXSSUnset) { | |
759 m_policy->reportDuplicateDirective(name); | |
760 m_reflectedXSSDisposition = ReflectedXSSInvalid; | |
761 return; | |
762 } | |
763 | |
764 if (value.isEmpty()) { | |
765 m_reflectedXSSDisposition = ReflectedXSSInvalid; | |
766 m_policy->reportInvalidReflectedXSS(value); | |
767 return; | |
768 } | |
769 | |
770 Vector<UChar> characters; | |
771 value.appendTo(characters); | |
772 | |
773 const UChar* position = characters.data(); | |
774 const UChar* end = position + characters.size(); | |
775 | |
776 skipWhile<UChar, isASCIISpace>(position, end); | |
777 const UChar* begin = position; | |
778 skipWhile<UChar, isNotASCIISpace>(position, end); | |
779 | |
780 // value1 | |
781 // ^ | |
782 if (equalIgnoringCase("allow", begin, position - begin)) { | |
783 m_reflectedXSSDisposition = AllowReflectedXSS; | |
784 } else if (equalIgnoringCase("filter", begin, position - begin)) { | |
785 m_reflectedXSSDisposition = FilterReflectedXSS; | |
786 } else if (equalIgnoringCase("block", begin, position - begin)) { | |
787 m_reflectedXSSDisposition = BlockReflectedXSS; | |
788 } else { | |
789 m_reflectedXSSDisposition = ReflectedXSSInvalid; | |
790 m_policy->reportInvalidReflectedXSS(value); | |
791 return; | |
792 } | |
793 | |
794 skipWhile<UChar, isASCIISpace>(position, end); | |
795 if (position == end && m_reflectedXSSDisposition != ReflectedXSSUnset) | |
796 return; | |
797 | |
798 // value1 value2 | |
799 // ^ | |
800 m_reflectedXSSDisposition = ReflectedXSSInvalid; | |
801 m_policy->reportInvalidReflectedXSS(value); | |
802 } | |
803 | |
804 void CSPDirectiveList::parseReferrer(const String& name, const String& value) | |
805 { | |
806 if (m_didSetReferrerPolicy) { | |
807 m_policy->reportDuplicateDirective(name); | |
808 m_referrerPolicy = ReferrerPolicyNever; | |
809 return; | |
810 } | |
811 | |
812 m_didSetReferrerPolicy = true; | |
813 | |
814 if (value.isEmpty()) { | |
815 m_policy->reportInvalidReferrer(value); | |
816 m_referrerPolicy = ReferrerPolicyNever; | |
817 return; | |
818 } | |
819 | |
820 Vector<UChar> characters; | |
821 value.appendTo(characters); | |
822 | |
823 const UChar* position = characters.data(); | |
824 const UChar* end = position + characters.size(); | |
825 | |
826 skipWhile<UChar, isASCIISpace>(position, end); | |
827 const UChar* begin = position; | |
828 skipWhile<UChar, isNotASCIISpace>(position, end); | |
829 | |
830 // value1 | |
831 // ^ | |
832 if (equalIgnoringCase("always", begin, position - begin)) { | |
833 m_referrerPolicy = ReferrerPolicyAlways; | |
834 } else if (equalIgnoringCase("default", begin, position - begin)) { | |
835 m_referrerPolicy = ReferrerPolicyDefault; | |
836 } else if (equalIgnoringCase("never", begin, position - begin)) { | |
837 m_referrerPolicy = ReferrerPolicyNever; | |
838 } else if (equalIgnoringCase("origin", begin, position - begin)) { | |
839 m_referrerPolicy = ReferrerPolicyOrigin; | |
840 } else { | |
841 m_referrerPolicy = ReferrerPolicyNever; | |
842 m_policy->reportInvalidReferrer(value); | |
843 return; | |
844 } | |
845 | |
846 skipWhile<UChar, isASCIISpace>(position, end); | |
847 if (position == end) | |
848 return; | |
849 | |
850 // value1 value2 | |
851 // ^ | |
852 m_referrerPolicy = ReferrerPolicyNever; | |
853 m_policy->reportInvalidReferrer(value); | |
854 | |
855 } | |
856 | |
857 void CSPDirectiveList::addDirective(const String& name, const String& value) | |
858 { | |
859 ASSERT(!name.isEmpty()); | |
860 | |
861 if (equalIgnoringCase(name, defaultSrc)) { | |
862 setCSPDirective<SourceListDirective>(name, value, m_defaultSrc); | |
863 } else if (equalIgnoringCase(name, scriptSrc)) { | |
864 setCSPDirective<SourceListDirective>(name, value, m_scriptSrc); | |
865 m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed()); | |
866 } else if (equalIgnoringCase(name, objectSrc)) { | |
867 setCSPDirective<SourceListDirective>(name, value, m_objectSrc); | |
868 } else if (equalIgnoringCase(name, frameSrc)) { | |
869 setCSPDirective<SourceListDirective>(name, value, m_frameSrc); | |
870 } else if (equalIgnoringCase(name, imgSrc)) { | |
871 setCSPDirective<SourceListDirective>(name, value, m_imgSrc); | |
872 } else if (equalIgnoringCase(name, styleSrc)) { | |
873 setCSPDirective<SourceListDirective>(name, value, m_styleSrc); | |
874 m_policy->usesStyleHashAlgorithms(m_styleSrc->hashAlgorithmsUsed()); | |
875 } else if (equalIgnoringCase(name, fontSrc)) { | |
876 setCSPDirective<SourceListDirective>(name, value, m_fontSrc); | |
877 } else if (equalIgnoringCase(name, mediaSrc)) { | |
878 setCSPDirective<SourceListDirective>(name, value, m_mediaSrc); | |
879 } else if (equalIgnoringCase(name, connectSrc)) { | |
880 setCSPDirective<SourceListDirective>(name, value, m_connectSrc); | |
881 } else if (equalIgnoringCase(name, sandbox)) { | |
882 applySandboxPolicy(name, value); | |
883 } else if (equalIgnoringCase(name, reportURI)) { | |
884 parseReportURI(name, value); | |
885 } else if (m_policy->experimentalFeaturesEnabled()) { | |
886 if (equalIgnoringCase(name, baseURI)) | |
887 setCSPDirective<SourceListDirective>(name, value, m_baseURI); | |
888 else if (equalIgnoringCase(name, childSrc)) | |
889 setCSPDirective<SourceListDirective>(name, value, m_childSrc); | |
890 else if (equalIgnoringCase(name, formAction)) | |
891 setCSPDirective<SourceListDirective>(name, value, m_formAction); | |
892 else if (equalIgnoringCase(name, frameAncestors)) | |
893 setCSPDirective<SourceListDirective>(name, value, m_frameAncestors); | |
894 else if (equalIgnoringCase(name, pluginTypes)) | |
895 setCSPDirective<MediaListDirective>(name, value, m_pluginTypes); | |
896 else if (equalIgnoringCase(name, reflectedXSS)) | |
897 parseReflectedXSS(name, value); | |
898 else if (equalIgnoringCase(name, referrer)) | |
899 parseReferrer(name, value); | |
900 else | |
901 m_policy->reportUnsupportedDirective(name); | |
902 } else { | |
903 m_policy->reportUnsupportedDirective(name); | |
904 } | |
905 } | |
906 | |
907 ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContextClient* client) | 132 ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContextClient* client) |
908 : m_client(client) | 133 : m_client(client) |
909 , m_overrideInlineStyleAllowed(false) | 134 , m_overrideInlineStyleAllowed(false) |
910 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) | 135 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) |
911 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) | 136 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) |
912 { | 137 { |
913 } | 138 } |
914 | 139 |
915 ContentSecurityPolicy::~ContentSecurityPolicy() | 140 ContentSecurityPolicy::~ContentSecurityPolicy() |
916 { | 141 { |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1561 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. | 786 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. |
1562 return !m_violationReportsSent.contains(report.impl()->hash()); | 787 return !m_violationReportsSent.contains(report.impl()->hash()); |
1563 } | 788 } |
1564 | 789 |
1565 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 790 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
1566 { | 791 { |
1567 m_violationReportsSent.add(report.impl()->hash()); | 792 m_violationReportsSent.add(report.impl()->hash()); |
1568 } | 793 } |
1569 | 794 |
1570 } // namespace WebCore | 795 } // namespace WebCore |
OLD | NEW |