1/*
2 * Copyright (C) 2011 Google, Inc. All rights reserved.
3 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "ContentSecurityPolicyDirectiveList.h"
29
30#include "ContentSecurityPolicyDirectiveNames.h"
31#include "Document.h"
32#include "Frame.h"
33#include "ParsingUtilities.h"
34#include "SecurityContext.h"
35
36namespace WebCore {
37
38static bool isDirectiveNameCharacter(UChar c)
39{
40 return isASCIIAlphanumeric(c) || c == '-';
41}
42
43static bool isDirectiveValueCharacter(UChar c)
44{
45 return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR
46}
47
48static inline bool checkEval(ContentSecurityPolicySourceListDirective* directive)
49{
50 return !directive || directive->allowEval();
51}
52
53static inline bool checkInline(ContentSecurityPolicySourceListDirective* directive)
54{
55 return !directive || directive->allowInline();
56}
57
58static inline bool checkSource(ContentSecurityPolicySourceListDirective* directive, const URL& url, bool didReceiveRedirectResponse = false, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone shouldAllowEmptyURLIfSourceListEmpty = ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone::No)
59{
60 return !directive || directive->allows(url, didReceiveRedirectResponse, shouldAllowEmptyURLIfSourceListEmpty);
61}
62
63static inline bool checkHash(ContentSecurityPolicySourceListDirective* directive, const ContentSecurityPolicyHash& hash)
64{
65 return !directive || directive->allows(hash);
66}
67
68static inline bool checkNonce(ContentSecurityPolicySourceListDirective* directive, const String& nonce)
69{
70 return !directive || directive->allows(nonce);
71}
72
73// Used to compute the comparison URL when checking frame-ancestors. We do this weird conversion so that child
74// frames of a page with a unique origin (e.g. about:blank) are not blocked due to their frame-ancestors policy
75// and do not need to add the parent's URL to their policy. The latter could allow the child page to be framed
76// by anyone. See <https://github.com/w3c/webappsec/issues/311> for more details.
77static inline URL urlFromOrigin(const SecurityOrigin& origin)
78{
79 return { URL { }, origin.toString() };
80}
81
82static inline bool checkFrameAncestors(ContentSecurityPolicySourceListDirective* directive, const Frame& frame)
83{
84 if (!directive)
85 return true;
86 bool didReceiveRedirectResponse = false;
87 for (Frame* current = frame.tree().parent(); current; current = current->tree().parent()) {
88 URL origin = urlFromOrigin(current->document()->securityOrigin());
89 if (!origin.isValid() || !directive->allows(origin, didReceiveRedirectResponse, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone::No))
90 return false;
91 }
92 return true;
93}
94
95static inline bool checkFrameAncestors(ContentSecurityPolicySourceListDirective* directive, const Vector<RefPtr<SecurityOrigin>>& ancestorOrigins)
96{
97 if (!directive)
98 return true;
99 bool didReceiveRedirectResponse = false;
100 for (auto& origin : ancestorOrigins) {
101 URL originURL = urlFromOrigin(*origin);
102 if (!originURL.isValid() || !directive->allows(originURL, didReceiveRedirectResponse, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone::No))
103 return false;
104 }
105 return true;
106}
107
108static inline bool checkMediaType(ContentSecurityPolicyMediaListDirective* directive, const String& type, const String& typeAttribute)
109{
110 if (!directive)
111 return true;
112 if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
113 return false;
114 return directive->allows(type);
115}
116
117ContentSecurityPolicyDirectiveList::ContentSecurityPolicyDirectiveList(ContentSecurityPolicy& policy, ContentSecurityPolicyHeaderType type)
118 : m_policy(policy)
119 , m_headerType(type)
120{
121 m_reportOnly = (type == ContentSecurityPolicyHeaderType::Report || type == ContentSecurityPolicyHeaderType::PrefixedReport);
122}
123
124std::unique_ptr<ContentSecurityPolicyDirectiveList> ContentSecurityPolicyDirectiveList::create(ContentSecurityPolicy& policy, const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicy::PolicyFrom from)
125{
126 auto directives = std::make_unique<ContentSecurityPolicyDirectiveList>(policy, type);
127 directives->parse(header, from);
128
129 if (!checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
130 String evalDisabledMessage = makeString("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n");
131 directives->setEvalDisabledErrorMessage(evalDisabledMessage);
132 String webAssemblyDisabledMessage = makeString("Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n");
133 directives->setWebAssemblyDisabledErrorMessage(webAssemblyDisabledMessage);
134 }
135
136 if (directives->isReportOnly() && directives->reportURIs().isEmpty())
137 policy.reportMissingReportURI(header);
138
139 return directives;
140}
141
142ContentSecurityPolicySourceListDirective* ContentSecurityPolicyDirectiveList::operativeDirective(ContentSecurityPolicySourceListDirective* directive) const
143{
144 return directive ? directive : m_defaultSrc.get();
145}
146
147const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeEval() const
148{
149 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
150 if (checkEval(operativeDirective))
151 return nullptr;
152 return operativeDirective;
153}
154
155const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeInlineScript() const
156{
157 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
158 if (checkInline(operativeDirective))
159 return nullptr;
160 return operativeDirective;
161}
162
163const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeInlineStyle() const
164{
165 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_styleSrc.get());
166 if (checkInline(operativeDirective))
167 return nullptr;
168 return operativeDirective;
169}
170
171const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptHash(const ContentSecurityPolicyHash& hash) const
172{
173 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
174 if (checkHash(operativeDirective, hash))
175 return nullptr;
176 return operativeDirective;
177}
178
179const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForStyleHash(const ContentSecurityPolicyHash& hash) const
180{
181 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_styleSrc.get());
182 if (checkHash(operativeDirective, hash))
183 return nullptr;
184 return operativeDirective;
185}
186
187const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptNonce(const String& nonce) const
188{
189 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
190 if (checkNonce(operativeDirective, nonce))
191 return nullptr;
192 return operativeDirective;
193}
194
195const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForStyleNonce(const String& nonce) const
196{
197 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_styleSrc.get());
198 if (checkNonce(operativeDirective, nonce))
199 return nullptr;
200 return operativeDirective;
201}
202
203const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForBaseURI(const URL& url) const
204{
205 if (checkSource(m_baseURI.get(), url))
206 return nullptr;
207 return m_baseURI.get();
208}
209
210const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForChildContext(const URL& url, bool didReceiveRedirectResponse) const
211{
212 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_childSrc.get());
213 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
214 return nullptr;
215 return operativeDirective;
216}
217
218const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForConnectSource(const URL& url, bool didReceiveRedirectResponse) const
219{
220 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_connectSrc.get());
221 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
222 return nullptr;
223 return operativeDirective;
224}
225
226const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFont(const URL& url, bool didReceiveRedirectResponse) const
227{
228 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_fontSrc.get());
229 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
230 return nullptr;
231 return operativeDirective;
232}
233
234const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFormAction(const URL& url, bool didReceiveRedirectResponse) const
235{
236 if (checkSource(m_formAction.get(), url, didReceiveRedirectResponse))
237 return nullptr;
238 return m_formAction.get();
239}
240
241const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFrame(const URL& url, bool didReceiveRedirectResponse) const
242{
243 if (url.protocolIsAbout())
244 return nullptr;
245
246 // We must enforce the frame-src directive (if specified) before enforcing the child-src directive for a nested browsing
247 // context by <https://w3c.github.io/webappsec-csp/2/#directive-child-src-nested> (29 August 2015).
248 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_frameSrc ? m_frameSrc.get() : m_childSrc.get());
249 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
250 return nullptr;
251 return operativeDirective;
252}
253
254const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFrameAncestor(const Frame& frame) const
255{
256 if (checkFrameAncestors(m_frameAncestors.get(), frame))
257 return nullptr;
258 return m_frameAncestors.get();
259}
260
261const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFrameAncestorOrigins(const Vector<RefPtr<SecurityOrigin>>& ancestorOrigins) const
262{
263 if (checkFrameAncestors(m_frameAncestors.get(), ancestorOrigins))
264 return nullptr;
265 return m_frameAncestors.get();
266}
267
268const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForImage(const URL& url, bool didReceiveRedirectResponse) const
269{
270 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_imgSrc.get());
271 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
272 return nullptr;
273 return operativeDirective;
274}
275
276#if ENABLE(APPLICATION_MANIFEST)
277const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForManifest(const URL& url, bool didReceiveRedirectResponse) const
278{
279 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_manifestSrc.get());
280 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
281 return nullptr;
282 return operativeDirective;
283}
284#endif // ENABLE(APPLICATION_MANIFEST)
285
286const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForMedia(const URL& url, bool didReceiveRedirectResponse) const
287{
288 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_mediaSrc.get());
289 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
290 return nullptr;
291 return operativeDirective;
292}
293
294const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForObjectSource(const URL& url, bool didReceiveRedirectResponse, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone shouldAllowEmptyURLIfSourceListEmpty) const
295{
296 if (url.protocolIsAbout())
297 return nullptr;
298 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_objectSrc.get());
299 if (checkSource(operativeDirective, url, didReceiveRedirectResponse, shouldAllowEmptyURLIfSourceListEmpty))
300 return nullptr;
301 return operativeDirective;
302}
303
304const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForPluginType(const String& type, const String& typeAttribute) const
305{
306 if (checkMediaType(m_pluginTypes.get(), type, typeAttribute))
307 return nullptr;
308 return m_pluginTypes.get();
309}
310
311const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScript(const URL& url, bool didReceiveRedirectResponse) const
312{
313 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
314 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
315 return nullptr;
316 return operativeDirective;
317}
318
319const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForStyle(const URL& url, bool didReceiveRedirectResponse) const
320{
321 ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_styleSrc.get());
322 if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
323 return nullptr;
324 return operativeDirective;
325}
326
327// policy = directive-list
328// directive-list = [ directive *( ";" [ directive ] ) ]
329//
330void ContentSecurityPolicyDirectiveList::parse(const String& policy, ContentSecurityPolicy::PolicyFrom policyFrom)
331{
332 m_header = policy;
333 if (policy.isEmpty())
334 return;
335
336 auto characters = StringView(policy).upconvertedCharacters();
337 const UChar* position = characters;
338 const UChar* end = position + policy.length();
339
340 while (position < end) {
341 const UChar* directiveBegin = position;
342 skipUntil<UChar>(position, end, ';');
343
344 String name, value;
345 if (parseDirective(directiveBegin, position, name, value)) {
346 ASSERT(!name.isEmpty());
347 if (policyFrom == ContentSecurityPolicy::PolicyFrom::Inherited) {
348 if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::upgradeInsecureRequests))
349 continue;
350 } else if (policyFrom == ContentSecurityPolicy::PolicyFrom::HTTPEquivMeta) {
351 if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::sandbox)
352 || equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::reportURI)
353 || equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::frameAncestors)) {
354 m_policy.reportInvalidDirectiveInHTTPEquivMeta(name);
355 continue;
356 }
357 } else if (policyFrom == ContentSecurityPolicy::PolicyFrom::InheritedForPluginDocument) {
358 if (!equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::pluginTypes)
359 && !equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::reportURI))
360 continue;
361 }
362 addDirective(name, value);
363 }
364
365 ASSERT(position == end || *position == ';');
366 skipExactly<UChar>(position, end, ';');
367 }
368}
369
370// directive = *WSP [ directive-name [ WSP directive-value ] ]
371// directive-name = 1*( ALPHA / DIGIT / "-" )
372// directive-value = *( WSP / <VCHAR except ";"> )
373//
374bool ContentSecurityPolicyDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
375{
376 ASSERT(name.isEmpty());
377 ASSERT(value.isEmpty());
378
379 const UChar* position = begin;
380 skipWhile<UChar, isASCIISpace>(position, end);
381
382 // Empty directive (e.g. ";;;"). Exit early.
383 if (position == end)
384 return false;
385
386 const UChar* nameBegin = position;
387 skipWhile<UChar, isDirectiveNameCharacter>(position, end);
388
389 // The directive-name must be non-empty.
390 if (nameBegin == position) {
391 skipWhile<UChar, isNotASCIISpace>(position, end);
392 m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin));
393 return false;
394 }
395
396 name = String(nameBegin, position - nameBegin);
397
398 if (position == end)
399 return true;
400
401 if (!skipExactly<UChar, isASCIISpace>(position, end)) {
402 skipWhile<UChar, isNotASCIISpace>(position, end);
403 m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin));
404 return false;
405 }
406
407 skipWhile<UChar, isASCIISpace>(position, end);
408
409 const UChar* valueBegin = position;
410 skipWhile<UChar, isDirectiveValueCharacter>(position, end);
411
412 if (position != end) {
413 m_policy.reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
414 return false;
415 }
416
417 // The directive-value may be empty.
418 if (valueBegin == position)
419 return true;
420
421 value = String(valueBegin, position - valueBegin);
422 return true;
423}
424
425void ContentSecurityPolicyDirectiveList::parseReportURI(const String& name, const String& value)
426{
427 if (!m_reportURIs.isEmpty()) {
428 m_policy.reportDuplicateDirective(name);
429 return;
430 }
431
432 auto characters = StringView(value).upconvertedCharacters();
433 const UChar* position = characters;
434 const UChar* end = position + value.length();
435
436 while (position < end) {
437 skipWhile<UChar, isASCIISpace>(position, end);
438
439 const UChar* urlBegin = position;
440 skipWhile<UChar, isNotASCIISpace>(position, end);
441
442 if (urlBegin < position)
443 m_reportURIs.append(value.substring(urlBegin - characters, position - urlBegin));
444 }
445}
446
447
448template<class CSPDirectiveType>
449void ContentSecurityPolicyDirectiveList::setCSPDirective(const String& name, const String& value, std::unique_ptr<CSPDirectiveType>& directive)
450{
451 if (directive) {
452 m_policy.reportDuplicateDirective(name);
453 return;
454 }
455 directive = std::make_unique<CSPDirectiveType>(*this, name, value);
456}
457
458void ContentSecurityPolicyDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
459{
460 if (m_reportOnly) {
461 m_policy.reportInvalidDirectiveInReportOnlyMode(name);
462 return;
463 }
464 if (m_haveSandboxPolicy) {
465 m_policy.reportDuplicateDirective(name);
466 return;
467 }
468 m_haveSandboxPolicy = true;
469 String invalidTokens;
470 m_policy.enforceSandboxFlags(SecurityContext::parseSandboxPolicy(sandboxPolicy, invalidTokens));
471 if (!invalidTokens.isNull())
472 m_policy.reportInvalidSandboxFlags(invalidTokens);
473}
474
475void ContentSecurityPolicyDirectiveList::setUpgradeInsecureRequests(const String& name)
476{
477 if (m_reportOnly) {
478 m_policy.reportInvalidDirectiveInReportOnlyMode(name);
479 return;
480 }
481 if (m_upgradeInsecureRequests) {
482 m_policy.reportDuplicateDirective(name);
483 return;
484 }
485 m_upgradeInsecureRequests = true;
486 m_policy.setUpgradeInsecureRequests(true);
487}
488
489void ContentSecurityPolicyDirectiveList::setBlockAllMixedContentEnabled(const String& name)
490{
491 if (m_hasBlockAllMixedContentDirective) {
492 m_policy.reportDuplicateDirective(name);
493 return;
494 }
495 m_hasBlockAllMixedContentDirective = true;
496}
497
498void ContentSecurityPolicyDirectiveList::addDirective(const String& name, const String& value)
499{
500 ASSERT(!name.isEmpty());
501
502 if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::defaultSrc)) {
503 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_defaultSrc);
504 m_policy.addHashAlgorithmsForInlineScripts(m_defaultSrc->hashAlgorithmsUsed());
505 m_policy.addHashAlgorithmsForInlineStylesheets(m_defaultSrc->hashAlgorithmsUsed());
506 } else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::scriptSrc)) {
507 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_scriptSrc);
508 m_policy.addHashAlgorithmsForInlineScripts(m_scriptSrc->hashAlgorithmsUsed());
509 } else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::styleSrc)) {
510 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_styleSrc);
511 m_policy.addHashAlgorithmsForInlineStylesheets(m_styleSrc->hashAlgorithmsUsed());
512 } else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::objectSrc))
513 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_objectSrc);
514 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::frameSrc)) {
515 // FIXME: Log to console "The frame-src directive is deprecated. Use the child-src directive instead."
516 // See <https://bugs.webkit.org/show_bug.cgi?id=155773>.
517 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_frameSrc);
518 } else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::imgSrc))
519 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_imgSrc);
520 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::fontSrc))
521 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_fontSrc);
522#if ENABLE(APPLICATION_MANIFEST)
523 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::manifestSrc))
524 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_manifestSrc);
525#endif
526 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::mediaSrc))
527 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_mediaSrc);
528 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::connectSrc))
529 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_connectSrc);
530 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::childSrc))
531 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_childSrc);
532 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::formAction))
533 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_formAction);
534 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::baseURI))
535 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_baseURI);
536 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::frameAncestors)) {
537 if (m_reportOnly) {
538 m_policy.reportInvalidDirectiveInReportOnlyMode(name);
539 return;
540 }
541 setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_frameAncestors);
542 } else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::pluginTypes))
543 setCSPDirective<ContentSecurityPolicyMediaListDirective>(name, value, m_pluginTypes);
544 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::sandbox))
545 applySandboxPolicy(name, value);
546 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::reportURI))
547 parseReportURI(name, value);
548 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::upgradeInsecureRequests))
549 setUpgradeInsecureRequests(name);
550 else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::blockAllMixedContent))
551 setBlockAllMixedContentEnabled(name);
552 else
553 m_policy.reportUnsupportedDirective(name);
554}
555
556} // namespace WebCore
557