1d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// found in the LICENSE file.
4d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
5d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "config.h"
6d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/csp/CSPDirectiveList.h"
7d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
8197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/Document.h"
9d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
10e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/inspector/ConsoleMessage.h"
11d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/ParsingUtilities.h"
12d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/weborigin/KURL.h"
13d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/text/WTFString.h"
14d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
15c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
16d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
17d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
18d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : m_policy(policy)
19d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_headerType(type)
20d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_headerSource(source)
21d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_reportOnly(false)
22d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_haveSandboxPolicy(false)
23d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_reflectedXSSDisposition(ReflectedXSSUnset)
24d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_didSetReferrerPolicy(false)
25d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_referrerPolicy(ReferrerPolicyDefault)
26d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
27d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_reportOnly = type == ContentSecurityPolicyHeaderTypeReport;
28d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
29d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
30d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
31d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
32d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type, source));
33d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    directives->parse(begin, end);
34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        String message = "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";
37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        directives->setEvalDisabledErrorMessage(message);
38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (directives->isReportOnly() && directives->reportEndpoints().isEmpty())
41d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        policy->reportMissingReportURI(String(begin, end - begin));
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return directives.release();
44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const
47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_policy->logToConsole(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message));
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header);
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid CSPDirectiveList::reportViolationWithFrame(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, LocalFrame* frame) const
547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_policy->logToConsole(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message), frame);
577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header, frame);
58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_policy->logToConsole(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt()));
647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header);
65d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
67e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void CSPDirectiveList::reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& message, const KURL& blockedURL, ScriptState* scriptState) const
68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
69e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    String reportMessage = m_reportOnly ? "[Report Only] " + message : message;
70e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, reportMessage);
71e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    consoleMessage->setScriptState(scriptState);
727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_policy->logToConsole(consoleMessage.release());
737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportEndpoints, m_header);
74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !directive || directive->allowEval();
79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !directive || (directive->allowInline() && !directive->isHashOrNoncePresent());
84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
85d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const
87d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
88a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    return !directive || directive->allowNonce(nonce);
89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
90d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkHash(SourceListDirective* directive, const CSPHashValue& hashValue) const
92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
93a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    return !directive || directive->allowHash(hashValue);
94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& url) const
97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !directive || directive->allows(url);
99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
100d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkAncestors(SourceListDirective* directive, LocalFrame* frame) const
102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!frame || !directive)
104d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
106f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (Frame* current = frame->tree().parent(); current; current = current->tree().parent()) {
107f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        // FIXME: To make this work for out-of-process iframes, we need to propagate URL information of ancestor frames across processes.
108f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (!current->isLocalFrame() || !directive->allows(toLocalFrame(current)->document()->url()))
109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return false;
110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
112d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
113d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
115d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!directive)
117d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return directive->allows(type);
121d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
122d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
123d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
124d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
125d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return directive ? directive : m_defaultSrc.get();
126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
127d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
128d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive, SourceListDirective* override) const
129d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return directive ? directive : override;
131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
133f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liubool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, ScriptState* scriptState) const
134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (checkEval(directive))
136d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String suffix = String();
139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (directive == m_defaultSrc)
140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
142f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    reportViolationWithState(directive->text(), ContentSecurityPolicy::ScriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), scriptState);
143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_reportOnly) {
144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportBlockedScriptExecutionToInspector(directive->text());
145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
149d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (checkMediaType(directive, type, typeAttribute))
153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String message = consoleMessage + "\'" + directive->text() + "\'.";
156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (typeAttribute.isEmpty())
157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        message = message + " When enforcing the 'plugin-types' directive, the plugin's media type must be explicitly declared with a 'type' attribute on the containing element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>').";
158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    reportViolation(directive->text(), ContentSecurityPolicy::PluginTypes, message + "\n", KURL());
160d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return denyIfEnforcingPolicy();
161d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
164d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
165d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (checkInline(directive))
166d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
167d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String suffix = String();
169d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (directive->allowInline() && directive->isHashOrNoncePresent()) {
170d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // If inline is allowed, but a hash or nonce is present, we ignore 'unsafe-inline'. Throw a reasonable error.
171d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        suffix = " Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.";
172d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else {
173d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        suffix = " Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.";
174d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (directive == m_defaultSrc)
175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            suffix = suffix + " Note also that '" + String(isScript ? "script" : "style") + "-src' was not explicitly set, so 'default-src' is used as a fallback.";
176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    reportViolationWithLocation(directive->text(), isScript ? ContentSecurityPolicy::ScriptSrc : ContentSecurityPolicy::StyleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), contextURL, contextLine);
179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_reportOnly) {
181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (isScript)
182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_policy->reportBlockedScriptExecutionToInspector(directive->text());
183d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
184d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
185d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const KURL& url, const String& effectiveDirective) const
189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (checkSource(directive, url))
191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String prefix;
194d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (ContentSecurityPolicy::BaseURI == effectiveDirective)
195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to set the document's base URI to '";
196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::ChildSrc == effectiveDirective)
197d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to create a child context containing '";
198d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::ConnectSrc == effectiveDirective)
199d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to connect to '";
200d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::FontSrc == effectiveDirective)
201d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to load the font '";
202d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::FormAction == effectiveDirective)
203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to send form data to '";
204d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::FrameSrc == effectiveDirective)
205d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to frame '";
206d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::ImgSrc == effectiveDirective)
207d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to load the image '";
208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::MediaSrc == effectiveDirective)
209d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to load media from '";
210d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::ObjectSrc == effectiveDirective)
211d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to load plugin data from '";
212d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::ScriptSrc == effectiveDirective)
213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to load the script '";
214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    else if (ContentSecurityPolicy::StyleSrc == effectiveDirective)
215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        prefix = "Refused to load the stylesheet '";
216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
217d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String suffix = String();
218d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (directive == m_defaultSrc)
219d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
220d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
221d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    reportViolation(directive->text(), effectiveDirective, prefix + url.elidedString() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url);
222d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return denyIfEnforcingPolicy();
223d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
224d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
2257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool CSPDirectiveList::checkAncestorsAndReportViolation(SourceListDirective* directive, LocalFrame* frame, const KURL& url) const
226d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
227d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (checkAncestors(directive, frame))
228d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
229d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    reportViolationWithFrame(directive->text(), "frame-ancestors", "Refused to display '" + url.elidedString() + "' in a frame because an ancestor violates the following Content Security Policy directive: \"" + directive->text() + "\".", url, frame);
231d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return denyIfEnforcingPolicy();
232d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
233d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
234d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
235d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
236d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
237d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (reportingStatus == ContentSecurityPolicy::SendReport)
238d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
239d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
240d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return checkInline(operativeDirective(m_scriptSrc.get()));
241d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
242d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
243d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
244d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
245d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline event handler because it violates the following Content Security Policy directive: "));
246d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (reportingStatus == ContentSecurityPolicy::SendReport)
247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
248d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return checkInline(operativeDirective(m_scriptSrc.get()));
249d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
250d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
251d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
252d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline script because it violates the following Content Security Policy directive: "));
254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
255d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true) :
256d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkInline(operativeDirective(m_scriptSrc.get()));
257d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
258d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
259d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
260d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
261d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to apply inline style because it violates the following Content Security Policy directive: "));
262d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
263d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false) :
264d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkInline(operativeDirective(m_styleSrc.get()));
265d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
266d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
267f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liubool CSPDirectiveList::allowEval(ScriptState* scriptState, ContentSecurityPolicy::ReportingStatus reportingStatus) const
268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
269d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "));
270d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
271d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
272f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, scriptState) :
273d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkEval(operativeDirective(m_scriptSrc.get()));
274d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
276d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
277d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
278d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
279d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.elidedString() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
280d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkMediaType(m_pluginTypes.get(), type, typeAttribute);
281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
284d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
285d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
286d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, ContentSecurityPolicy::ScriptSrc) :
287d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(operativeDirective(m_scriptSrc.get()), url);
288d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
289d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
290d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
29210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (url.protocolIsAbout())
293d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
294d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
295d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, ContentSecurityPolicy::ObjectSrc) :
296d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(operativeDirective(m_objectSrc.get()), url);
297d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
298d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
299d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
300d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
30110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (url.protocolIsAbout())
302d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
303d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // 'frame-src' is the only directive which overrides something other than the default sources.
305d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // It overrides 'child-src', which overrides the default sources. So, we do this nested set
306d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // of calls to 'operativeDirective()' to grab 'frame-src' if it exists, 'child-src' if it
307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // doesn't, and 'defaut-src' if neither are available.
308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //
309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // All of this only applies, of course, if we're in CSP 1.1. In CSP 1.0, 'frame-src'
310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // overrides 'default-src' directly.
311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SourceListDirective* whichDirective = m_policy->experimentalFeaturesEnabled() ?
312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        operativeDirective(m_frameSrc.get(), operativeDirective(m_childSrc.get())) :
313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        operativeDirective(m_frameSrc.get());
314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
316d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(whichDirective, url, ContentSecurityPolicy::FrameSrc) :
317d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(whichDirective, url);
318d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
320d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
321d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
322d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
323d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, ContentSecurityPolicy::ImgSrc) :
324d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(operativeDirective(m_imgSrc.get()), url);
325d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
326d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
327d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
328d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
329d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
330d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, ContentSecurityPolicy::StyleSrc) :
331d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(operativeDirective(m_styleSrc.get()), url);
332d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
333d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
335d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
336d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
337d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, ContentSecurityPolicy::FontSrc) :
338d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(operativeDirective(m_fontSrc.get()), url);
339d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
340d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
341d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
342d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
343d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
344d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, ContentSecurityPolicy::MediaSrc) :
345d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(operativeDirective(m_mediaSrc.get()), url);
346d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
347d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
348d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
349d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
350d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
351d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, ContentSecurityPolicy::ConnectSrc) :
352d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(operativeDirective(m_connectSrc.get()), url);
353d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
354d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
355d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
356d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
357d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
358d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(m_formAction.get(), url, ContentSecurityPolicy::FormAction) :
359d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(m_formAction.get(), url);
360d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
361d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
362d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
363d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
364d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
365d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(m_baseURI.get(), url, ContentSecurityPolicy::BaseURI) :
366d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(m_baseURI.get(), url);
367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
368d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
3697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool CSPDirectiveList::allowAncestors(LocalFrame* frame, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
371d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
3727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        checkAncestorsAndReportViolation(m_frameAncestors.get(), frame, url) :
373d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkAncestors(m_frameAncestors.get(), frame);
374d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
375d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
376d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
377d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
378d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return reportingStatus == ContentSecurityPolicy::SendReport ?
379d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSourceAndReportViolation(operativeDirective(m_childSrc.get()), url, ContentSecurityPolicy::ChildSrc) :
380d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        checkSource(operativeDirective(m_childSrc.get()), url);
381d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
385d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
386d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
387d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
388d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowStyleNonce(const String& nonce) const
389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
390d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
391d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
392d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
393d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowScriptHash(const CSPHashValue& hashValue) const
394d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
395d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return checkHash(operativeDirective(m_scriptSrc.get()), hashValue);
396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
397d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
398d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::allowStyleHash(const CSPHashValue& hashValue) const
399d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
400d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return checkHash(operativeDirective(m_styleSrc.get()), hashValue);
401d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
402d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
403d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// policy            = directive-list
404d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// directive-list    = [ directive *( ";" [ directive ] ) ]
405d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
406d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::parse(const UChar* begin, const UChar* end)
407d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
408d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_header = String(begin, end - begin);
409d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
410d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (begin == end)
411d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
412d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
413d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
414d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (position < end) {
415d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        const UChar* directiveBegin = position;
416d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipUntil<UChar>(position, end, ';');
417d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
418d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        String name, value;
419d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (parseDirective(directiveBegin, position, name, value)) {
420d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            ASSERT(!name.isEmpty());
421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            addDirective(name, value);
422d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
423d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
424d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        ASSERT(position == end || *position == ';');
425d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipExactly<UChar>(position, end, ';');
426d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
427d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
428d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
429d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// directive         = *WSP [ directive-name [ WSP directive-value ] ]
430d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// directive-name    = 1*( ALPHA / DIGIT / "-" )
431d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// directive-value   = *( WSP / <VCHAR except ";"> )
432d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
433d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
434d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
435d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(name.isEmpty());
436d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(value.isEmpty());
437d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
438d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
439d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIISpace>(position, end);
440d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
441d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Empty directive (e.g. ";;;"). Exit early.
442d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position == end)
443d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
444d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
445d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* nameBegin = position;
446d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isCSPDirectiveNameCharacter>(position, end);
447d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
448d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // The directive-name must be non-empty.
449d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (nameBegin == position) {
450d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipWhile<UChar, isNotASCIISpace>(position, end);
451d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
452d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
453d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
454d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
455d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    name = String(nameBegin, position - nameBegin);
456d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
457d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position == end)
458d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
459d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
460d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!skipExactly<UChar, isASCIISpace>(position, end)) {
461d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipWhile<UChar, isNotASCIISpace>(position, end);
462d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
463d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
464d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
465d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
466d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIISpace>(position, end);
467d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
468d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* valueBegin = position;
469d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isCSPDirectiveValueCharacter>(position, end);
470d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
471d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position != end) {
472d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
473d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
474d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
475d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
476d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // The directive-value may be empty.
477d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (valueBegin == position)
478d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
479d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
480d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    value = String(valueBegin, position - valueBegin);
481d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
482d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
483d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
484d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::parseReportURI(const String& name, const String& value)
485d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
4867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!m_reportEndpoints.isEmpty()) {
487d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportDuplicateDirective(name);
488d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
489d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
490d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
491d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    Vector<UChar> characters;
492d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    value.appendTo(characters);
493d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
494d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = characters.data();
495d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* end = position + characters.size();
496d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
497d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (position < end) {
498d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipWhile<UChar, isASCIISpace>(position, end);
499d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
500d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        const UChar* urlBegin = position;
501d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipWhile<UChar, isNotASCIISpace>(position, end);
502d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
503d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (urlBegin < position) {
504d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            String url = String(urlBegin, position - urlBegin);
5057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            m_reportEndpoints.append(url);
506d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
507d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
508d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
509d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
510d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
511d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)template<class CSPDirectiveType>
512d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive)
513d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
514d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (directive) {
515d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportDuplicateDirective(name);
516d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
517d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
518d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
519d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
520d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
521d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
522d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
523d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_reportOnly) {
524d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportInvalidInReportOnly(name);
525d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
526d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
527d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_haveSandboxPolicy) {
528d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportDuplicateDirective(name);
529d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
530d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
531d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_haveSandboxPolicy = true;
532d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String invalidTokens;
533d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidTokens));
534d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!invalidTokens.isNull())
535d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportInvalidSandboxFlags(invalidTokens);
536d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
537d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
538d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
539d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
540d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_reflectedXSSDisposition != ReflectedXSSUnset) {
541d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportDuplicateDirective(name);
542d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_reflectedXSSDisposition = ReflectedXSSInvalid;
543d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
544d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
545d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
546d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (value.isEmpty()) {
547d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_reflectedXSSDisposition = ReflectedXSSInvalid;
548d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportInvalidReflectedXSS(value);
549d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
550d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
551d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
552d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    Vector<UChar> characters;
553d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    value.appendTo(characters);
554d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
555d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = characters.data();
556d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* end = position + characters.size();
557d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
558d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIISpace>(position, end);
559d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* begin = position;
560d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isNotASCIISpace>(position, end);
561d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
562d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // value1
563d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //       ^
564d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (equalIgnoringCase("allow", begin, position - begin)) {
565d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_reflectedXSSDisposition = AllowReflectedXSS;
566d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase("filter", begin, position - begin)) {
567d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_reflectedXSSDisposition = FilterReflectedXSS;
568d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase("block", begin, position - begin)) {
569d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_reflectedXSSDisposition = BlockReflectedXSS;
570d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else {
571d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_reflectedXSSDisposition = ReflectedXSSInvalid;
572d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportInvalidReflectedXSS(value);
573d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
574d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
575d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
576d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIISpace>(position, end);
577d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position == end && m_reflectedXSSDisposition != ReflectedXSSUnset)
578d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
579d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
580d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // value1 value2
581d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //        ^
582d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_reflectedXSSDisposition = ReflectedXSSInvalid;
583d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_policy->reportInvalidReflectedXSS(value);
584d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
585d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
586d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::parseReferrer(const String& name, const String& value)
587d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
588d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_didSetReferrerPolicy) {
589d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportDuplicateDirective(name);
590d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_referrerPolicy = ReferrerPolicyNever;
591d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
592d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
593d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
594d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_didSetReferrerPolicy = true;
595d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
596d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (value.isEmpty()) {
597d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportInvalidReferrer(value);
598d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_referrerPolicy = ReferrerPolicyNever;
599d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
600d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
601d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
602d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    Vector<UChar> characters;
603d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    value.appendTo(characters);
604d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
605d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = characters.data();
606d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* end = position + characters.size();
607d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
608d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIISpace>(position, end);
609d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* begin = position;
610d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isNotASCIISpace>(position, end);
611d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
612d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // value1
613d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //       ^
614d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (equalIgnoringCase("always", begin, position - begin)) {
615d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_referrerPolicy = ReferrerPolicyAlways;
616d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase("default", begin, position - begin)) {
617d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_referrerPolicy = ReferrerPolicyDefault;
618d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase("never", begin, position - begin)) {
619d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_referrerPolicy = ReferrerPolicyNever;
620d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase("origin", begin, position - begin)) {
621d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_referrerPolicy = ReferrerPolicyOrigin;
622d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else {
623d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_referrerPolicy = ReferrerPolicyNever;
624d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportInvalidReferrer(value);
625d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
626d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
627d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
628d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIISpace>(position, end);
629d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position == end)
630d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
631d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
632d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // value1 value2
633d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //        ^
634d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_referrerPolicy = ReferrerPolicyNever;
635d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_policy->reportInvalidReferrer(value);
636d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
637d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
638d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
639d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPDirectiveList::addDirective(const String& name, const String& value)
640d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
641d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!name.isEmpty());
642d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
643d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (equalIgnoringCase(name, ContentSecurityPolicy::DefaultSrc)) {
644d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
645d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ScriptSrc)) {
646d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
647d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed());
648d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ObjectSrc)) {
649d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
650aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    } else if (equalIgnoringCase(name, ContentSecurityPolicy::FrameAncestors)) {
651aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        setCSPDirective<SourceListDirective>(name, value, m_frameAncestors);
652d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::FrameSrc)) {
653d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
654d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ImgSrc)) {
655d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
656d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::StyleSrc)) {
657d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
658d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->usesStyleHashAlgorithms(m_styleSrc->hashAlgorithmsUsed());
659d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::FontSrc)) {
660d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
661d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::MediaSrc)) {
662d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
663d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ConnectSrc)) {
664d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
665d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::Sandbox)) {
666d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        applySandboxPolicy(name, value);
667d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ReportURI)) {
668d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        parseReportURI(name, value);
669d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else if (m_policy->experimentalFeaturesEnabled()) {
670d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (equalIgnoringCase(name, ContentSecurityPolicy::BaseURI))
671d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            setCSPDirective<SourceListDirective>(name, value, m_baseURI);
672d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else if (equalIgnoringCase(name, ContentSecurityPolicy::ChildSrc))
673d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            setCSPDirective<SourceListDirective>(name, value, m_childSrc);
674d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else if (equalIgnoringCase(name, ContentSecurityPolicy::FormAction))
675d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            setCSPDirective<SourceListDirective>(name, value, m_formAction);
676d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else if (equalIgnoringCase(name, ContentSecurityPolicy::PluginTypes))
677d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
678d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else if (equalIgnoringCase(name, ContentSecurityPolicy::ReflectedXSS))
679d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            parseReflectedXSS(name, value);
680d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer))
681d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            parseReferrer(name, value);
682d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else
683d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_policy->reportUnsupportedDirective(name);
684d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else {
685d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportUnsupportedDirective(name);
686d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
687d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
688d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
689d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
690c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
691