Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactor CSPDirective to support non-sourcelist types.

https://bugs.webkit.org/show_bug.cgi?id=94252

Patch by Mike West <mkwst@chromium.org> on 2012-08-16
Reviewed by Adam Barth.

Source/WebCore:

The 'CSPDirective' was built to support source list Content Security
Policy directives like 'script-src' or 'object-src'. It doesn't support
new directive types like 'script-nonce' or 'plugin-types'. That
functionality has been implemented by hanging state off of
CSPDirectiveList, which isn't a great solution.

This patch pulls the source list functionality out of CSPDirective and
into SourceListDirective, and likewise pulls the nonce and media list
functionality into NonceDirective and MediaListDirective.

No new tests have been added; this refactoring should be externally
transparent, and the current CSP tests should continue to pass.

* page/ContentSecurityPolicy.cpp:
(WebCore::CSPDirective::CSPDirective):
(CSPDirective):
(WebCore::CSPDirective::text):
(WebCore::CSPDirective::policy):
    CSPDirective is now a parent class for NonceDirective,
    MediaListDirective, and SourceListDirective. It stores a pointer
    to the ContentSecurityPolicy object in order to facilitate logging,
    which now needs to happen at this level, rather than higher up in
    CSPDirectiveList.
(WebCore):
(NonceDirective):
(WebCore::NonceDirective::NonceDirective):
(WebCore::NonceDirective::allows):
(WebCore::NonceDirective::parse):
    Pull the nonce parsing code and state out of CSPDirectiveList
    and into this new class.
(MediaListDirective):
(WebCore::MediaListDirective::MediaListDirective):
(WebCore::MediaListDirective::allows):
(WebCore::MediaListDirective::parse):
    Pull the media list parsing code and state out of CSPDirectiveList
    and into this new class.
(SourceListDirective):
(WebCore::SourceListDirective::SourceListDirective):
(WebCore::SourceListDirective::allows):
    Pull the source list functionality out of CSPDirective
    and into this new class.
(CSPDirectiveList):
(WebCore::CSPDirectiveList::checkEval):
(WebCore::CSPDirectiveList::checkInline):
(WebCore::CSPDirectiveList::checkNonce):
(WebCore::CSPDirectiveList::checkSource):
(WebCore::CSPDirectiveList::checkMediaType):
(WebCore::CSPDirectiveList::operativeDirective):
(WebCore::CSPDirectiveList::checkEvalAndReportViolation):
(WebCore::CSPDirectiveList::checkNonceAndReportViolation):
(WebCore::CSPDirectiveList::checkMediaTypeAndReportViolation):
(WebCore::CSPDirectiveList::checkInlineAndReportViolation):
(WebCore::CSPDirectiveList::checkSourceAndReportViolation):
(WebCore::CSPDirectiveList::allowJavaScriptURLs):
(WebCore::CSPDirectiveList::allowInlineEventHandlers):
(WebCore::CSPDirectiveList::allowScriptNonce):
(WebCore::CSPDirectiveList::allowPluginType):
(WebCore::CSPDirectiveList::setCSPDirective):
(WebCore::CSPDirectiveList::addDirective):
    Use the new classes rather than CSPDirective (or no directive
    at all, in the case of nonces and plugin types).

LayoutTests:

* http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt:
    This test was buggy. Now it writes out the full directive text as it
    ought to.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@125817 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information...
commit 79b937c6b7fb6629f0b1e9debe74e4aa9beabd8e 1 parent 26b2c70
commit-queue authored
View
11 LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2012-08-16 Mike West <mkwst@chromium.org>
+
+ Refactor CSPDirective to support non-sourcelist types.
+ https://bugs.webkit.org/show_bug.cgi?id=94252
+
+ Reviewed by Adam Barth.
+
+ * http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt:
+ This test was buggy. Now it writes out the full directive text as it
+ ought to.
+
2012-08-16 Kiran Muppala <cmuppala@apple.com>
Update test expectations for fast/overflow/line-clamp-and-columns.html on mac
View
2  LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt
@@ -12,7 +12,7 @@ CONSOLE MESSAGE: line 7: Refused to load 'http://127.0.0.1:8000/security/content
CONSOLE MESSAGE: Ignoring invalid Content Security Policy script nonce: 'nonces have no spaces'.
-CONSOLE MESSAGE: line 7: Refused to load 'http://127.0.0.1:8000/security/contentSecurityPolicy/resources/script.js' because it violates the following Content Security Policy directive: "script-nonce ".
+CONSOLE MESSAGE: line 7: Refused to load 'http://127.0.0.1:8000/security/contentSecurityPolicy/resources/script.js' because it violates the following Content Security Policy directive: "script-nonce nonces have no spaces".
None of these scripts should execute, as all the nonces are invalid.
View
69 Source/WebCore/ChangeLog
@@ -1,3 +1,72 @@
+2012-08-16 Mike West <mkwst@chromium.org>
+
+ Refactor CSPDirective to support non-sourcelist types.
+ https://bugs.webkit.org/show_bug.cgi?id=94252
+
+ Reviewed by Adam Barth.
+
+ The 'CSPDirective' was built to support source list Content Security
+ Policy directives like 'script-src' or 'object-src'. It doesn't support
+ new directive types like 'script-nonce' or 'plugin-types'. That
+ functionality has been implemented by hanging state off of
+ CSPDirectiveList, which isn't a great solution.
+
+ This patch pulls the source list functionality out of CSPDirective and
+ into SourceListDirective, and likewise pulls the nonce and media list
+ functionality into NonceDirective and MediaListDirective.
+
+ No new tests have been added; this refactoring should be externally
+ transparent, and the current CSP tests should continue to pass.
+
+ * page/ContentSecurityPolicy.cpp:
+ (WebCore::CSPDirective::CSPDirective):
+ (CSPDirective):
+ (WebCore::CSPDirective::text):
+ (WebCore::CSPDirective::policy):
+ CSPDirective is now a parent class for NonceDirective,
+ MediaListDirective, and SourceListDirective. It stores a pointer
+ to the ContentSecurityPolicy object in order to facilitate logging,
+ which now needs to happen at this level, rather than higher up in
+ CSPDirectiveList.
+ (WebCore):
+ (NonceDirective):
+ (WebCore::NonceDirective::NonceDirective):
+ (WebCore::NonceDirective::allows):
+ (WebCore::NonceDirective::parse):
+ Pull the nonce parsing code and state out of CSPDirectiveList
+ and into this new class.
+ (MediaListDirective):
+ (WebCore::MediaListDirective::MediaListDirective):
+ (WebCore::MediaListDirective::allows):
+ (WebCore::MediaListDirective::parse):
+ Pull the media list parsing code and state out of CSPDirectiveList
+ and into this new class.
+ (SourceListDirective):
+ (WebCore::SourceListDirective::SourceListDirective):
+ (WebCore::SourceListDirective::allows):
+ Pull the source list functionality out of CSPDirective
+ and into this new class.
+ (CSPDirectiveList):
+ (WebCore::CSPDirectiveList::checkEval):
+ (WebCore::CSPDirectiveList::checkInline):
+ (WebCore::CSPDirectiveList::checkNonce):
+ (WebCore::CSPDirectiveList::checkSource):
+ (WebCore::CSPDirectiveList::checkMediaType):
+ (WebCore::CSPDirectiveList::operativeDirective):
+ (WebCore::CSPDirectiveList::checkEvalAndReportViolation):
+ (WebCore::CSPDirectiveList::checkNonceAndReportViolation):
+ (WebCore::CSPDirectiveList::checkMediaTypeAndReportViolation):
+ (WebCore::CSPDirectiveList::checkInlineAndReportViolation):
+ (WebCore::CSPDirectiveList::checkSourceAndReportViolation):
+ (WebCore::CSPDirectiveList::allowJavaScriptURLs):
+ (WebCore::CSPDirectiveList::allowInlineEventHandlers):
+ (WebCore::CSPDirectiveList::allowScriptNonce):
+ (WebCore::CSPDirectiveList::allowPluginType):
+ (WebCore::CSPDirectiveList::setCSPDirective):
+ (WebCore::CSPDirectiveList::addDirective):
+ Use the new classes rather than CSPDirective (or no directive
+ at all, in the case of nonces and plugin types).
+
2012-08-16 Adam Barth <abarth@webkit.org>
Null checks of m_frame->document()->domWindow() aren't needed
View
379 Source/WebCore/page/ContentSecurityPolicy.cpp
@@ -536,27 +536,162 @@ void CSPSourceList::addSourceUnsafeEval()
class CSPDirective {
public:
CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
- : m_sourceList(policy, name)
+ : m_name(name)
, m_text(name + ' ' + value)
- , m_selfURL(policy->url())
+ , m_policy(policy)
+ {
+ }
+
+ const String& text() const { return m_text; }
+
+protected:
+ const ContentSecurityPolicy* policy() const { return m_policy; }
+
+private:
+ String m_name;
+ String m_text;
+ ContentSecurityPolicy* m_policy;
+};
+
+class NonceDirective : public CSPDirective {
+public:
+ NonceDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy)
+ {
+ parse(value);
+ }
+
+ bool allows(const String& nonce) const
+ {
+ return (!m_scriptNonce.isEmpty() && nonce.stripWhiteSpace() == m_scriptNonce);
+ }
+
+private:
+ void parse(const String& value)
+ {
+ String nonce;
+ const UChar* position = value.characters();
+ const UChar* end = position + value.length();
+
+ skipWhile<isASCIISpace>(position, end);
+ const UChar* nonceBegin = position;
+ if (position == end) {
+ policy()->reportInvalidNonce(String());
+ m_scriptNonce = "";
+ return;
+ }
+ skipWhile<isNonceCharacter>(position, end);
+ if (nonceBegin < position)
+ nonce = String(nonceBegin, position - nonceBegin);
+
+ // Trim off trailing whitespace: If we're not at the end of the string, log
+ // an error.
+ skipWhile<isASCIISpace>(position, end);
+ if (position < end) {
+ policy()->reportInvalidNonce(value);
+ m_scriptNonce = "";
+ } else
+ m_scriptNonce = nonce;
+ }
+
+ String m_scriptNonce;
+};
+
+class MediaListDirective : public CSPDirective {
+public:
+ MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy)
+ {
+ parse(value);
+ }
+
+ bool allows(const String& type)
+ {
+ return m_pluginTypes.contains(type);
+ }
+
+private:
+ void parse(const String& value)
+ {
+ const UChar* begin = value.characters();
+ const UChar* position = begin;
+ const UChar* end = begin + value.length();
+
+ // 'plugin-types ____;' OR 'plugin-types;'
+ if (value.isEmpty()) {
+ policy()->reportInvalidPluginTypes(value);
+ return;
+ }
+
+ while (position < end) {
+ // _____ OR _____mime1/mime1
+ // ^ ^
+ skipWhile<isASCIISpace>(position, end);
+ if (position == end)
+ return;
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ begin = position;
+ if (!skipExactly<isMediaTypeCharacter>(position, end)) {
+ skipWhile<isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ skipWhile<isMediaTypeCharacter>(position, end);
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ if (!skipExactly(position, end, '/')) {
+ skipWhile<isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ if (!skipExactly<isMediaTypeCharacter>(position, end)) {
+ skipWhile<isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ skipWhile<isMediaTypeCharacter>(position, end);
+
+ // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error
+ // ^ ^ ^
+ if (position < end && isNotASCIISpace(*position)) {
+ skipWhile<isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ m_pluginTypes.add(String(begin, position - begin));
+
+ ASSERT(position == end || isASCIISpace(*position));
+ }
+ }
+
+ HashSet<String> m_pluginTypes;
+};
+
+class SourceListDirective : public CSPDirective {
+public:
+ SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy)
+ , m_sourceList(policy, name)
{
m_sourceList.parse(value);
}
bool allows(const KURL& url)
{
- return m_sourceList.matches(url.isEmpty() ? m_selfURL : url);
+ return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
}
bool allowInline() const { return m_sourceList.allowInline(); }
bool allowEval() const { return m_sourceList.allowEval(); }
- const String& text() { return m_text; }
-
private:
CSPSourceList m_sourceList;
- String m_text;
- KURL m_selfURL;
};
class CSPDirectiveList {
@@ -598,22 +733,23 @@ class CSPDirectiveList {
void addDirective(const String& name, const String& value);
void applySandboxPolicy(const String& name, const String& sandboxPolicy);
- void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirective>&);
+ template <class CSPDirectiveType>
+ void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>&);
- CSPDirective* operativeDirective(CSPDirective*) const;
+ SourceListDirective* operativeDirective(SourceListDirective*) const;
void reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL = KURL(), const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack> = 0) const;
- bool checkEval(CSPDirective*) const;
- bool checkInline(CSPDirective*) const;
- bool checkNonce(const String&) const;
- bool checkSource(CSPDirective*, const KURL&) const;
- bool checkPluginType(const String& type, const String& typeAttribute) const;
+ bool checkEval(SourceListDirective*) const;
+ bool checkInline(SourceListDirective*) const;
+ bool checkNonce(NonceDirective*, const String&) const;
+ bool checkSource(SourceListDirective*, const KURL&) const;
+ bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
- bool checkEvalAndReportViolation(CSPDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack> = 0) const;
- bool checkInlineAndReportViolation(CSPDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
- bool checkNonceAndReportViolation(const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
- bool checkSourceAndReportViolation(CSPDirective*, const KURL&, const String& type) const;
- bool checkPluginTypeAndReportViolation(const String& type, const String& typeAttribute, const String& consoleMessage) const;
+ bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack> = 0) const;
+ bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
+ bool checkNonceAndReportViolation(NonceDirective*, const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
+ bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& type) const;
+ bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
bool denyIfEnforcingPolicy() const { return m_reportOnly; }
@@ -623,21 +759,20 @@ class CSPDirectiveList {
bool m_reportOnly;
bool m_haveSandboxPolicy;
- OwnPtr<CSPDirective> m_defaultSrc;
- OwnPtr<CSPDirective> m_scriptSrc;
- OwnPtr<CSPDirective> m_objectSrc;
- OwnPtr<CSPDirective> m_frameSrc;
- OwnPtr<CSPDirective> m_imgSrc;
- OwnPtr<CSPDirective> m_styleSrc;
- OwnPtr<CSPDirective> m_fontSrc;
- OwnPtr<CSPDirective> m_mediaSrc;
- OwnPtr<CSPDirective> m_connectSrc;
- OwnPtr<CSPDirective> m_formAction;
+ OwnPtr<MediaListDirective> m_pluginTypes;
+ OwnPtr<NonceDirective> m_scriptNonce;
+ OwnPtr<SourceListDirective> m_connectSrc;
+ OwnPtr<SourceListDirective> m_defaultSrc;
+ OwnPtr<SourceListDirective> m_fontSrc;
+ OwnPtr<SourceListDirective> m_formAction;
+ 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;
- HashSet<String> m_pluginTypes;
- String m_pluginTypesDirective;
- String m_scriptNonce;
};
CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy)
@@ -671,43 +806,41 @@ void CSPDirectiveList::reportViolation(const String& directiveText, const String
m_policy->reportViolation(directiveText, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, callStack);
}
-bool CSPDirectiveList::checkEval(CSPDirective* directive) const
+bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
{
return !directive || directive->allowEval();
}
-bool CSPDirectiveList::checkInline(CSPDirective* directive) const
+bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
{
return !directive || directive->allowInline();
}
-bool CSPDirectiveList::checkNonce(const String& nonce) const
+bool CSPDirectiveList::checkNonce(NonceDirective* directive, const String& nonce) const
{
- return (m_scriptNonce.isNull()
- || (!m_scriptNonce.isEmpty()
- && nonce.stripWhiteSpace() == m_scriptNonce));
+ return !directive || directive->allows(nonce);
}
-bool CSPDirectiveList::checkSource(CSPDirective* directive, const KURL& url) const
+bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& url) const
{
return !directive || directive->allows(url);
}
-bool CSPDirectiveList::checkPluginType(const String& type, const String& typeAttribute) const
+bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
{
- if (m_pluginTypesDirective.isNull())
+ if (!directive)
return true;
if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
return false;
- return m_pluginTypes.contains(type);
+ return directive->allows(type);
}
-CSPDirective* CSPDirectiveList::operativeDirective(CSPDirective* directive) const
+SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
{
return directive ? directive : m_defaultSrc.get();
}
-bool CSPDirectiveList::checkEvalAndReportViolation(CSPDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const
+bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const
{
if (checkEval(directive))
return true;
@@ -715,24 +848,24 @@ bool CSPDirectiveList::checkEvalAndReportViolation(CSPDirective* directive, cons
return denyIfEnforcingPolicy();
}
-bool CSPDirectiveList::checkNonceAndReportViolation(const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
+bool CSPDirectiveList::checkNonceAndReportViolation(NonceDirective* directive, const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
{
- if (checkNonce(nonce))
+ if (checkNonce(directive, nonce))
return true;
- reportViolation(m_scriptNonce, consoleMessage + "\"script-nonce " + m_scriptNonce + "\".\n", KURL(), contextURL, contextLine);
+ reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\".\n", KURL(), contextURL, contextLine);
return denyIfEnforcingPolicy();
}
-bool CSPDirectiveList::checkPluginTypeAndReportViolation(const String& type, const String& typeAttribute, const String& consoleMessage) const
+bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
{
- if (checkPluginType(type, typeAttribute))
+ if (checkMediaType(directive, type, typeAttribute))
return true;
- reportViolation(m_pluginTypesDirective, consoleMessage + "'plugin-types " + m_pluginTypesDirective + "'.\n", KURL());
+ reportViolation(directive->text(), consoleMessage + "\'" + directive->text() + "\'.\n", KURL());
return denyIfEnforcingPolicy();
}
-bool CSPDirectiveList::checkInlineAndReportViolation(CSPDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
+bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
{
if (checkInline(directive))
return true;
@@ -740,7 +873,7 @@ bool CSPDirectiveList::checkInlineAndReportViolation(CSPDirective* directive, co
return denyIfEnforcingPolicy();
}
-bool CSPDirectiveList::checkSourceAndReportViolation(CSPDirective* directive, const KURL& url, const String& type) const
+bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const KURL& url, const String& type) const
{
if (checkSource(directive, url))
return true;
@@ -760,10 +893,10 @@ bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::
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)
- && checkNonceAndReportViolation(String(), consoleMessage, contextURL, contextLine));
+ && checkNonceAndReportViolation(m_scriptNonce.get(), String(), consoleMessage, contextURL, contextLine));
} else {
return (checkInline(operativeDirective(m_scriptSrc.get()))
- && checkNonce(String()));
+ && checkNonce(m_scriptNonce.get(), String()));
}
}
@@ -772,10 +905,10 @@ bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, 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)
- && checkNonceAndReportViolation(String(), consoleMessage, contextURL, contextLine));
+ && checkNonceAndReportViolation(m_scriptNonce.get(), String(), consoleMessage, contextURL, contextLine));
} else {
return (checkInline(operativeDirective(m_scriptSrc.get()))
- && checkNonce(String()));
+ && checkNonce(m_scriptNonce.get(), String()));
}
}
@@ -807,15 +940,15 @@ bool CSPDirectiveList::allowScriptNonce(const String& nonce, const String& conte
{
DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute script because it violates the following Content Security Policy directive: "));
if (url.isEmpty())
- return checkNonceAndReportViolation(nonce, consoleMessage, contextURL, contextLine);
- return checkNonceAndReportViolation(nonce, "Refused to load '" + url.string() + "' because it violates the following Content Security Policy directive: ", contextURL, contextLine);
+ return checkNonceAndReportViolation(m_scriptNonce.get(), nonce, consoleMessage, contextURL, contextLine);
+ return checkNonceAndReportViolation(m_scriptNonce.get(), nonce, "Refused to load '" + url.string() + "' because it violates the following Content Security Policy directive: ", contextURL, contextLine);
}
bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
{
return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkPluginTypeAndReportViolation(type, typeAttribute, "Refused to load '" + url.string() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
- checkPluginType(type, typeAttribute);
+ checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.string() + "' (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
@@ -1001,111 +1134,15 @@ void CSPDirectiveList::parseReportURI(const String& name, const String& value)
}
}
-void CSPDirectiveList::parseScriptNonce(const String& name, const String& value)
-{
- if (!m_scriptNonce.isNull()) {
- m_policy->reportDuplicateDirective(name);
- return;
- }
-
- String nonce;
- const UChar* position = value.characters();
- const UChar* end = position + value.length();
-
- skipWhile<isASCIISpace>(position, end);
- const UChar* nonceBegin = position;
- if (position == end) {
- m_policy->reportInvalidNonce(String());
- m_scriptNonce = "";
- return;
- }
- skipWhile<isNonceCharacter>(position, end);
- if (nonceBegin < position)
- nonce = String(nonceBegin, position - nonceBegin);
-
- // Trim off trailing whitespace: If we're not at the end of the string, log
- // an error.
- skipWhile<isASCIISpace>(position, end);
- if (position < end) {
- m_policy->reportInvalidNonce(value);
- m_scriptNonce = "";
- } else
- m_scriptNonce = nonce;
-}
-
-void CSPDirectiveList::parsePluginTypes(const String& name, const String& value)
-{
- if (!m_pluginTypesDirective.isNull()) {
- m_policy->reportDuplicateDirective(name);
- return;
- }
-
- const UChar* begin = value.characters();
- const UChar* position = begin;
- const UChar* end = begin + value.length();
- m_pluginTypesDirective = value;
-
- // 'plugin-types ____;' OR 'plugin-types;'
- if (value.isEmpty()) {
- m_policy->reportInvalidPluginTypes(value);
- m_pluginTypesDirective = "";
- return;
- }
-
- while (position < end) {
- // _____ OR _____mime1/mime1
- // ^ ^
- skipWhile<isASCIISpace>(position, end);
- if (position == end)
- return;
-
- // mime1/mime1 mime2/mime2
- // ^
- begin = position;
- if (!skipExactly<isMediaTypeCharacter>(position, end)) {
- skipWhile<isNotASCIISpace>(position, end);
- m_policy->reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- skipWhile<isMediaTypeCharacter>(position, end);
-
- // mime1/mime1 mime2/mime2
- // ^
- if (!skipExactly(position, end, '/')) {
- skipWhile<isNotASCIISpace>(position, end);
- m_policy->reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
-
- // mime1/mime1 mime2/mime2
- // ^
- if (!skipExactly<isMediaTypeCharacter>(position, end)) {
- skipWhile<isNotASCIISpace>(position, end);
- m_policy->reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- skipWhile<isMediaTypeCharacter>(position, end);
-
- // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error
- // ^ ^ ^
- if (position < end && isNotASCIISpace(*position)) {
- skipWhile<isNotASCIISpace>(position, end);
- m_policy->reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- m_pluginTypes.add(String(begin, position - begin));
-
- ASSERT(position == end || isASCIISpace(*position));
- }
-}
-void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirective>& directive)
+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 CSPDirective(name, value, m_policy));
+ directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
}
void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
@@ -1140,34 +1177,34 @@ void CSPDirectiveList::addDirective(const String& name, const String& value)
ASSERT(!name.isEmpty());
if (equalIgnoringCase(name, defaultSrc))
- setCSPDirective(name, value, m_defaultSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
else if (equalIgnoringCase(name, scriptSrc))
- setCSPDirective(name, value, m_scriptSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
else if (equalIgnoringCase(name, objectSrc))
- setCSPDirective(name, value, m_objectSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
else if (equalIgnoringCase(name, frameSrc))
- setCSPDirective(name, value, m_frameSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
else if (equalIgnoringCase(name, imgSrc))
- setCSPDirective(name, value, m_imgSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
else if (equalIgnoringCase(name, styleSrc))
- setCSPDirective(name, value, m_styleSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
else if (equalIgnoringCase(name, fontSrc))
- setCSPDirective(name, value, m_fontSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
else if (equalIgnoringCase(name, mediaSrc))
- setCSPDirective(name, value, m_mediaSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
else if (equalIgnoringCase(name, connectSrc))
- setCSPDirective(name, value, m_connectSrc);
+ setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
else if (equalIgnoringCase(name, sandbox))
applySandboxPolicy(name, value);
else if (equalIgnoringCase(name, reportURI))
parseReportURI(name, value);
#if ENABLE(CSP_NEXT)
else if (equalIgnoringCase(name, formAction))
- setCSPDirective(name, value, m_formAction);
+ setCSPDirective<SourceListDirective>(name, value, m_formAction);
else if (equalIgnoringCase(name, pluginTypes))
- parsePluginTypes(name, value);
+ setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
else if (equalIgnoringCase(name, scriptNonce))
- parseScriptNonce(name, value);
+ setCSPDirective<NonceDirective>(name, value, m_scriptNonce);
#endif
else
m_policy->reportUnrecognizedDirective(name);
Please sign in to comment.
Something went wrong with that request. Please try again.