Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(912)

Unified Diff: Source/core/frame/ContentSecurityPolicy.cpp

Issue 180273012: Extract CSPDirectiveList from ContentSecurityPolicy. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/frame/ContentSecurityPolicy.h ('k') | Source/core/frame/csp/CSPDirectiveList.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/frame/ContentSecurityPolicy.cpp
diff --git a/Source/core/frame/ContentSecurityPolicy.cpp b/Source/core/frame/ContentSecurityPolicy.cpp
index 8caa910fcd7265856a979ef3ca3ef7e600e65167..3e6b30339f1770a917fb998bf970bbcdc99ea05b 100644
--- a/Source/core/frame/ContentSecurityPolicy.cpp
+++ b/Source/core/frame/ContentSecurityPolicy.cpp
@@ -35,6 +35,7 @@
#include "core/frame/DOMWindow.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/UseCounter.h"
+#include "core/frame/csp/CSPDirectiveList.h"
#include "core/frame/csp/CSPSource.h"
#include "core/frame/csp/CSPSourceList.h"
#include "core/frame/csp/MediaListDirective.h"
@@ -65,47 +66,47 @@
namespace WebCore {
// CSP 1.0 Directives
-static const char connectSrc[] = "connect-src";
-static const char defaultSrc[] = "default-src";
-static const char fontSrc[] = "font-src";
-static const char frameSrc[] = "frame-src";
-static const char imgSrc[] = "img-src";
-static const char mediaSrc[] = "media-src";
-static const char objectSrc[] = "object-src";
-static const char reportURI[] = "report-uri";
-static const char sandbox[] = "sandbox";
-static const char scriptSrc[] = "script-src";
-static const char styleSrc[] = "style-src";
+const char ContentSecurityPolicy::ConnectSrc[] = "connect-src";
+const char ContentSecurityPolicy::DefaultSrc[] = "default-src";
+const char ContentSecurityPolicy::FontSrc[] = "font-src";
+const char ContentSecurityPolicy::FrameSrc[] = "frame-src";
+const char ContentSecurityPolicy::ImgSrc[] = "img-src";
+const char ContentSecurityPolicy::MediaSrc[] = "media-src";
+const char ContentSecurityPolicy::ObjectSrc[] = "object-src";
+const char ContentSecurityPolicy::ReportURI[] = "report-uri";
+const char ContentSecurityPolicy::Sandbox[] = "sandbox";
+const char ContentSecurityPolicy::ScriptSrc[] = "script-src";
+const char ContentSecurityPolicy::StyleSrc[] = "style-src";
// CSP 1.1 Directives
-static const char baseURI[] = "base-uri";
-static const char childSrc[] = "child-src";
-static const char formAction[] = "form-action";
-static const char frameAncestors[] = "frame-ancestors";
-static const char pluginTypes[] = "plugin-types";
-static const char reflectedXSS[] = "reflected-xss";
-static const char referrer[] = "referrer";
+const char ContentSecurityPolicy::BaseURI[] = "base-uri";
+const char ContentSecurityPolicy::ChildSrc[] = "child-src";
+const char ContentSecurityPolicy::FormAction[] = "form-action";
+const char ContentSecurityPolicy::FrameAncestors[] = "frame-ancestors";
+const char ContentSecurityPolicy::PluginTypes[] = "plugin-types";
+const char ContentSecurityPolicy::ReflectedXSS[] = "reflected-xss";
+const char ContentSecurityPolicy::Referrer[] = "referrer";
bool ContentSecurityPolicy::isDirectiveName(const String& name)
{
- return (equalIgnoringCase(name, connectSrc)
- || equalIgnoringCase(name, defaultSrc)
- || equalIgnoringCase(name, fontSrc)
- || equalIgnoringCase(name, frameSrc)
- || equalIgnoringCase(name, imgSrc)
- || equalIgnoringCase(name, mediaSrc)
- || equalIgnoringCase(name, objectSrc)
- || equalIgnoringCase(name, reportURI)
- || equalIgnoringCase(name, sandbox)
- || equalIgnoringCase(name, scriptSrc)
- || equalIgnoringCase(name, styleSrc)
- || equalIgnoringCase(name, baseURI)
- || equalIgnoringCase(name, childSrc)
- || equalIgnoringCase(name, formAction)
- || equalIgnoringCase(name, frameAncestors)
- || equalIgnoringCase(name, pluginTypes)
- || equalIgnoringCase(name, reflectedXSS)
- || equalIgnoringCase(name, referrer)
+ return (equalIgnoringCase(name, ConnectSrc)
+ || equalIgnoringCase(name, DefaultSrc)
+ || equalIgnoringCase(name, FontSrc)
+ || equalIgnoringCase(name, FrameSrc)
+ || equalIgnoringCase(name, ImgSrc)
+ || equalIgnoringCase(name, MediaSrc)
+ || equalIgnoringCase(name, ObjectSrc)
+ || equalIgnoringCase(name, ReportURI)
+ || equalIgnoringCase(name, Sandbox)
+ || equalIgnoringCase(name, ScriptSrc)
+ || equalIgnoringCase(name, StyleSrc)
+ || equalIgnoringCase(name, BaseURI)
+ || equalIgnoringCase(name, ChildSrc)
+ || equalIgnoringCase(name, FormAction)
+ || equalIgnoringCase(name, FrameAncestors)
+ || equalIgnoringCase(name, PluginTypes)
+ || equalIgnoringCase(name, ReflectedXSS)
+ || equalIgnoringCase(name, Referrer)
);
}
@@ -128,782 +129,6 @@ static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b)
return a;
}
-class CSPDirectiveList {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
-
- void parse(const UChar* begin, const UChar* end);
-
- const String& header() const { return m_header; }
- ContentSecurityPolicyHeaderType headerType() const { return m_headerType; }
- ContentSecurityPolicyHeaderSource headerSource() const { return m_headerSource; }
-
- bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowEval(ScriptState*, ContentSecurityPolicy::ReportingStatus) const;
- bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-
- bool allowScriptFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowObjectFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowAncestors(LocalFrame*, ContentSecurityPolicy::ReportingStatus) const;
- bool allowChildContextFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowScriptNonce(const String&) const;
- bool allowStyleNonce(const String&) const;
- bool allowScriptHash(const CSPHashValue&) const;
- bool allowStyleHash(const CSPHashValue&) const;
-
- const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
- ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
- ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
- bool didSetReferrerPolicy() const { return m_didSetReferrerPolicy; }
- bool isReportOnly() const { return m_reportOnly; }
- const Vector<KURL>& reportURIs() const { return m_reportURIs; }
-
-private:
- CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
-
- bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
- void parseReportURI(const String& name, const String& value);
- void parsePluginTypes(const String& name, const String& value);
- void parseReflectedXSS(const String& name, const String& value);
- void parseReferrer(const String& name, const String& value);
- void addDirective(const String& name, const String& value);
- void applySandboxPolicy(const String& name, const String& sandboxPolicy);
-
- template <class CSPDirectiveType>
- void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>&);
-
- SourceListDirective* operativeDirective(SourceListDirective*) const;
- SourceListDirective* operativeDirective(SourceListDirective*, SourceListDirective* override) const;
- void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const;
- void reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
- void reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState*) const;
-
- bool checkEval(SourceListDirective*) const;
- bool checkInline(SourceListDirective*) const;
- bool checkNonce(SourceListDirective*, const String&) const;
- bool checkHash(SourceListDirective*, const CSPHashValue&) const;
- bool checkSource(SourceListDirective*, const KURL&) const;
- bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
- bool checkAncestors(SourceListDirective*, LocalFrame*) const;
-
- void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
-
- bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, ScriptState*) const;
- bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
-
- bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const;
- bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
- bool checkAncestorsAndReportViolation(SourceListDirective*, LocalFrame*) const;
-
- bool denyIfEnforcingPolicy() const { return m_reportOnly; }
-
- ContentSecurityPolicy* m_policy;
-
- String m_header;
- ContentSecurityPolicyHeaderType m_headerType;
- ContentSecurityPolicyHeaderSource m_headerSource;
-
- bool m_reportOnly;
- bool m_haveSandboxPolicy;
- ReflectedXSSDisposition m_reflectedXSSDisposition;
-
- bool m_didSetReferrerPolicy;
- ReferrerPolicy m_referrerPolicy;
-
- OwnPtr<MediaListDirective> m_pluginTypes;
- OwnPtr<SourceListDirective> m_baseURI;
- OwnPtr<SourceListDirective> m_childSrc;
- OwnPtr<SourceListDirective> m_connectSrc;
- OwnPtr<SourceListDirective> m_defaultSrc;
- OwnPtr<SourceListDirective> m_fontSrc;
- OwnPtr<SourceListDirective> m_formAction;
- OwnPtr<SourceListDirective> m_frameAncestors;
- OwnPtr<SourceListDirective> m_frameSrc;
- OwnPtr<SourceListDirective> m_imgSrc;
- OwnPtr<SourceListDirective> m_mediaSrc;
- OwnPtr<SourceListDirective> m_objectSrc;
- OwnPtr<SourceListDirective> m_scriptSrc;
- OwnPtr<SourceListDirective> m_styleSrc;
-
- Vector<KURL> m_reportURIs;
-
- String m_evalDisabledErrorMessage;
-};
-
-CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
- : m_policy(policy)
- , m_headerType(type)
- , m_headerSource(source)
- , m_reportOnly(false)
- , m_haveSandboxPolicy(false)
- , m_reflectedXSSDisposition(ReflectedXSSUnset)
- , m_didSetReferrerPolicy(false)
- , m_referrerPolicy(ReferrerPolicyDefault)
-{
- m_reportOnly = type == ContentSecurityPolicyHeaderTypeReport;
-}
-
-PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
-{
- OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type, source));
- directives->parse(begin, end);
-
- if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
- 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";
- directives->setEvalDisabledErrorMessage(message);
- }
-
- if (directives->isReportOnly() && directives->reportURIs().isEmpty())
- policy->reportMissingReportURI(String(begin, end - begin));
-
- return directives.release();
-}
-
-void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const
-{
- String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
- m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
- m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-void CSPDirectiveList::reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
-{
- String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
- m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt());
- m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-void CSPDirectiveList::reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState* state) const
-{
- String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
- m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, state);
- m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
-{
- return !directive || directive->allowEval();
-}
-
-bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
-{
- return !directive || (directive->allowInline() && !directive->isHashOrNoncePresent());
-}
-
-bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const
-{
- return !directive || directive->allowNonce(nonce);
-}
-
-bool CSPDirectiveList::checkHash(SourceListDirective* directive, const CSPHashValue& hashValue) const
-{
- return !directive || directive->allowHash(hashValue);
-}
-
-bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& url) const
-{
- return !directive || directive->allows(url);
-}
-
-bool CSPDirectiveList::checkAncestors(SourceListDirective* directive, LocalFrame* frame) const
-{
- if (!frame || !directive)
- return true;
-
- for (LocalFrame* current = frame->tree().parent(); current; current = current->tree().parent()) {
- if (!directive->allows(current->document()->url()))
- return false;
- }
- return true;
-}
-
-bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
-{
- if (!directive)
- return true;
- if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
- return false;
- return directive->allows(type);
-}
-
-SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
-{
- return directive ? directive : m_defaultSrc.get();
-}
-
-SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive, SourceListDirective* override) const
-{
- return directive ? directive : override;
-}
-
-bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, ScriptState* state) const
-{
- if (checkEval(directive))
- return true;
-
- String suffix = String();
- if (directive == m_defaultSrc)
- suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
-
- reportViolationWithState(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), state);
- if (!m_reportOnly) {
- m_policy->reportBlockedScriptExecutionToInspector(directive->text());
- return false;
- }
- return true;
-}
-
-bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
-{
- if (checkMediaType(directive, type, typeAttribute))
- return true;
-
- String message = consoleMessage + "\'" + directive->text() + "\'.";
- if (typeAttribute.isEmpty())
- 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]\" ...>').";
-
- reportViolation(directive->text(), pluginTypes, message + "\n", KURL());
- return denyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
-{
- if (checkInline(directive))
- return true;
-
- String suffix = String();
- if (directive->allowInline() && directive->isHashOrNoncePresent()) {
- // If inline is allowed, but a hash or nonce is present, we ignore 'unsafe-inline'. Throw a reasonable error.
- suffix = " Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.";
- } else {
- suffix = " Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.";
- if (directive == m_defaultSrc)
- suffix = suffix + " Note also that '" + String(isScript ? "script" : "style") + "-src' was not explicitly set, so 'default-src' is used as a fallback.";
- }
-
- reportViolationWithLocation(directive->text(), isScript ? scriptSrc : styleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), contextURL, contextLine);
-
- if (!m_reportOnly) {
- if (isScript)
- m_policy->reportBlockedScriptExecutionToInspector(directive->text());
- return false;
- }
- return true;
-}
-
-bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const KURL& url, const String& effectiveDirective) const
-{
- if (checkSource(directive, url))
- return true;
-
- String prefix;
- if (baseURI == effectiveDirective)
- prefix = "Refused to set the document's base URI to '";
- else if (childSrc == effectiveDirective)
- prefix = "Refused to create a child context containing '";
- else if (connectSrc == effectiveDirective)
- prefix = "Refused to connect to '";
- else if (fontSrc == effectiveDirective)
- prefix = "Refused to load the font '";
- else if (formAction == effectiveDirective)
- prefix = "Refused to send form data to '";
- else if (frameSrc == effectiveDirective)
- prefix = "Refused to frame '";
- else if (imgSrc == effectiveDirective)
- prefix = "Refused to load the image '";
- else if (mediaSrc == effectiveDirective)
- prefix = "Refused to load media from '";
- else if (objectSrc == effectiveDirective)
- prefix = "Refused to load plugin data from '";
- else if (scriptSrc == effectiveDirective)
- prefix = "Refused to load the script '";
- else if (styleSrc == effectiveDirective)
- prefix = "Refused to load the stylesheet '";
-
- String suffix = String();
- if (directive == m_defaultSrc)
- suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
-
- reportViolation(directive->text(), effectiveDirective, prefix + url.elidedString() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url);
- return denyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::checkAncestorsAndReportViolation(SourceListDirective* directive, LocalFrame* frame) const
-{
- if (checkAncestors(directive, frame))
- return true;
-
- reportViolation(directive->text(), "frame-ancestors", "Refused to display '" + frame->document()->url().elidedString() + " in a frame because an ancestor violates the following Content Security Policy directive: \"" + directive->text() + "\".", frame->document()->url());
- return denyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::SendReport)
- return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
-
- return checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline event handler because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::SendReport)
- return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
- return checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline script because it violates the following Content Security Policy directive: "));
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true) :
- checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to apply inline style because it violates the following Content Security Policy directive: "));
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false) :
- checkInline(operativeDirective(m_styleSrc.get()));
-}
-
-bool CSPDirectiveList::allowEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- 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: "));
-
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, state) :
- checkEval(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.elidedString() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
- checkMediaType(m_pluginTypes.get(), type, typeAttribute);
-}
-
-bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, scriptSrc) :
- checkSource(operativeDirective(m_scriptSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (url.isBlankURL())
- return true;
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, objectSrc) :
- checkSource(operativeDirective(m_objectSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (url.isBlankURL())
- return true;
-
- // 'frame-src' is the only directive which overrides something other than the default sources.
- // It overrides 'child-src', which overrides the default sources. So, we do this nested set
- // of calls to 'operativeDirective()' to grab 'frame-src' if it exists, 'child-src' if it
- // doesn't, and 'defaut-src' if neither are available.
- //
- // All of this only applies, of course, if we're in CSP 1.1. In CSP 1.0, 'frame-src'
- // overrides 'default-src' directly.
- SourceListDirective* whichDirective = m_policy->experimentalFeaturesEnabled() ?
- operativeDirective(m_frameSrc.get(), operativeDirective(m_childSrc.get())) :
- operativeDirective(m_frameSrc.get());
-
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(whichDirective, url, frameSrc) :
- checkSource(whichDirective, url);
-}
-
-bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, imgSrc) :
- checkSource(operativeDirective(m_imgSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, styleSrc) :
- checkSource(operativeDirective(m_styleSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, fontSrc) :
- checkSource(operativeDirective(m_fontSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, mediaSrc) :
- checkSource(operativeDirective(m_mediaSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, connectSrc) :
- checkSource(operativeDirective(m_connectSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(m_formAction.get(), url, formAction) :
- checkSource(m_formAction.get(), url);
-}
-
-bool CSPDirectiveList::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(m_baseURI.get(), url, baseURI) :
- checkSource(m_baseURI.get(), url);
-}
-
-bool CSPDirectiveList::allowAncestors(LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkAncestorsAndReportViolation(m_frameAncestors.get(), frame) :
- checkAncestors(m_frameAncestors.get(), frame);
-}
-
-bool CSPDirectiveList::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_childSrc.get()), url, childSrc) :
- checkSource(operativeDirective(m_childSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
-{
- return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
-}
-
-bool CSPDirectiveList::allowStyleNonce(const String& nonce) const
-{
- return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
-}
-
-bool CSPDirectiveList::allowScriptHash(const CSPHashValue& hashValue) const
-{
- return checkHash(operativeDirective(m_scriptSrc.get()), hashValue);
-}
-
-bool CSPDirectiveList::allowStyleHash(const CSPHashValue& hashValue) const
-{
- return checkHash(operativeDirective(m_styleSrc.get()), hashValue);
-}
-
-// policy = directive-list
-// directive-list = [ directive *( ";" [ directive ] ) ]
-//
-void CSPDirectiveList::parse(const UChar* begin, const UChar* end)
-{
- m_header = String(begin, end - begin);
-
- if (begin == end)
- return;
-
- const UChar* position = begin;
- while (position < end) {
- const UChar* directiveBegin = position;
- skipUntil<UChar>(position, end, ';');
-
- String name, value;
- if (parseDirective(directiveBegin, position, name, value)) {
- ASSERT(!name.isEmpty());
- addDirective(name, value);
- }
-
- ASSERT(position == end || *position == ';');
- skipExactly<UChar>(position, end, ';');
- }
-}
-
-// directive = *WSP [ directive-name [ WSP directive-value ] ]
-// directive-name = 1*( ALPHA / DIGIT / "-" )
-// directive-value = *( WSP / <VCHAR except ";"> )
-//
-bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
-{
- ASSERT(name.isEmpty());
- ASSERT(value.isEmpty());
-
- const UChar* position = begin;
- skipWhile<UChar, isASCIISpace>(position, end);
-
- // Empty directive (e.g. ";;;"). Exit early.
- if (position == end)
- return false;
-
- const UChar* nameBegin = position;
- skipWhile<UChar, isCSPDirectiveNameCharacter>(position, end);
-
- // The directive-name must be non-empty.
- if (nameBegin == position) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
- return false;
- }
-
- name = String(nameBegin, position - nameBegin);
-
- if (position == end)
- return true;
-
- if (!skipExactly<UChar, isASCIISpace>(position, end)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
- return false;
- }
-
- skipWhile<UChar, isASCIISpace>(position, end);
-
- const UChar* valueBegin = position;
- skipWhile<UChar, isCSPDirectiveValueCharacter>(position, end);
-
- if (position != end) {
- m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
- return false;
- }
-
- // The directive-value may be empty.
- if (valueBegin == position)
- return true;
-
- value = String(valueBegin, position - valueBegin);
- return true;
-}
-
-void CSPDirectiveList::parseReportURI(const String& name, const String& value)
-{
- if (!m_reportURIs.isEmpty()) {
- m_policy->reportDuplicateDirective(name);
- return;
- }
-
- Vector<UChar> characters;
- value.appendTo(characters);
-
- const UChar* position = characters.data();
- const UChar* end = position + characters.size();
-
- while (position < end) {
- skipWhile<UChar, isASCIISpace>(position, end);
-
- const UChar* urlBegin = position;
- skipWhile<UChar, isNotASCIISpace>(position, end);
-
- if (urlBegin < position) {
- String url = String(urlBegin, position - urlBegin);
- m_reportURIs.append(m_policy->completeURL(url));
- }
- }
-}
-
-
-template<class CSPDirectiveType>
-void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive)
-{
- if (directive) {
- m_policy->reportDuplicateDirective(name);
- return;
- }
- directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
-}
-
-void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
-{
- if (m_reportOnly) {
- m_policy->reportInvalidInReportOnly(name);
- return;
- }
- if (m_haveSandboxPolicy) {
- m_policy->reportDuplicateDirective(name);
- return;
- }
- m_haveSandboxPolicy = true;
- String invalidTokens;
- m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidTokens));
- if (!invalidTokens.isNull())
- m_policy->reportInvalidSandboxFlags(invalidTokens);
-}
-
-void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
-{
- if (m_reflectedXSSDisposition != ReflectedXSSUnset) {
- m_policy->reportDuplicateDirective(name);
- m_reflectedXSSDisposition = ReflectedXSSInvalid;
- return;
- }
-
- if (value.isEmpty()) {
- m_reflectedXSSDisposition = ReflectedXSSInvalid;
- m_policy->reportInvalidReflectedXSS(value);
- return;
- }
-
- Vector<UChar> characters;
- value.appendTo(characters);
-
- const UChar* position = characters.data();
- const UChar* end = position + characters.size();
-
- skipWhile<UChar, isASCIISpace>(position, end);
- const UChar* begin = position;
- skipWhile<UChar, isNotASCIISpace>(position, end);
-
- // value1
- // ^
- if (equalIgnoringCase("allow", begin, position - begin)) {
- m_reflectedXSSDisposition = AllowReflectedXSS;
- } else if (equalIgnoringCase("filter", begin, position - begin)) {
- m_reflectedXSSDisposition = FilterReflectedXSS;
- } else if (equalIgnoringCase("block", begin, position - begin)) {
- m_reflectedXSSDisposition = BlockReflectedXSS;
- } else {
- m_reflectedXSSDisposition = ReflectedXSSInvalid;
- m_policy->reportInvalidReflectedXSS(value);
- return;
- }
-
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end && m_reflectedXSSDisposition != ReflectedXSSUnset)
- return;
-
- // value1 value2
- // ^
- m_reflectedXSSDisposition = ReflectedXSSInvalid;
- m_policy->reportInvalidReflectedXSS(value);
-}
-
-void CSPDirectiveList::parseReferrer(const String& name, const String& value)
-{
- if (m_didSetReferrerPolicy) {
- m_policy->reportDuplicateDirective(name);
- m_referrerPolicy = ReferrerPolicyNever;
- return;
- }
-
- m_didSetReferrerPolicy = true;
-
- if (value.isEmpty()) {
- m_policy->reportInvalidReferrer(value);
- m_referrerPolicy = ReferrerPolicyNever;
- return;
- }
-
- Vector<UChar> characters;
- value.appendTo(characters);
-
- const UChar* position = characters.data();
- const UChar* end = position + characters.size();
-
- skipWhile<UChar, isASCIISpace>(position, end);
- const UChar* begin = position;
- skipWhile<UChar, isNotASCIISpace>(position, end);
-
- // value1
- // ^
- if (equalIgnoringCase("always", begin, position - begin)) {
- m_referrerPolicy = ReferrerPolicyAlways;
- } else if (equalIgnoringCase("default", begin, position - begin)) {
- m_referrerPolicy = ReferrerPolicyDefault;
- } else if (equalIgnoringCase("never", begin, position - begin)) {
- m_referrerPolicy = ReferrerPolicyNever;
- } else if (equalIgnoringCase("origin", begin, position - begin)) {
- m_referrerPolicy = ReferrerPolicyOrigin;
- } else {
- m_referrerPolicy = ReferrerPolicyNever;
- m_policy->reportInvalidReferrer(value);
- return;
- }
-
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end)
- return;
-
- // value1 value2
- // ^
- m_referrerPolicy = ReferrerPolicyNever;
- m_policy->reportInvalidReferrer(value);
-
-}
-
-void CSPDirectiveList::addDirective(const String& name, const String& value)
-{
- ASSERT(!name.isEmpty());
-
- if (equalIgnoringCase(name, defaultSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
- } else if (equalIgnoringCase(name, scriptSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
- m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed());
- } else if (equalIgnoringCase(name, objectSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
- } else if (equalIgnoringCase(name, frameSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
- } else if (equalIgnoringCase(name, imgSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
- } else if (equalIgnoringCase(name, styleSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
- m_policy->usesStyleHashAlgorithms(m_styleSrc->hashAlgorithmsUsed());
- } else if (equalIgnoringCase(name, fontSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
- } else if (equalIgnoringCase(name, mediaSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
- } else if (equalIgnoringCase(name, connectSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
- } else if (equalIgnoringCase(name, sandbox)) {
- applySandboxPolicy(name, value);
- } else if (equalIgnoringCase(name, reportURI)) {
- parseReportURI(name, value);
- } else if (m_policy->experimentalFeaturesEnabled()) {
- if (equalIgnoringCase(name, baseURI))
- setCSPDirective<SourceListDirective>(name, value, m_baseURI);
- else if (equalIgnoringCase(name, childSrc))
- setCSPDirective<SourceListDirective>(name, value, m_childSrc);
- else if (equalIgnoringCase(name, formAction))
- setCSPDirective<SourceListDirective>(name, value, m_formAction);
- else if (equalIgnoringCase(name, frameAncestors))
- setCSPDirective<SourceListDirective>(name, value, m_frameAncestors);
- else if (equalIgnoringCase(name, pluginTypes))
- setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
- else if (equalIgnoringCase(name, reflectedXSS))
- parseReflectedXSS(name, value);
- else if (equalIgnoringCase(name, referrer))
- parseReferrer(name, value);
- else
- m_policy->reportUnsupportedDirective(name);
- } else {
- m_policy->reportUnsupportedDirective(name);
- }
-}
-
ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContextClient* client)
: m_client(client)
, m_overrideInlineStyleAllowed(false)
« no previous file with comments | « Source/core/frame/ContentSecurityPolicy.h ('k') | Source/core/frame/csp/CSPDirectiveList.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698