Title: [196012] trunk/Source/WebCore
Revision
196012
Author
[email protected]
Date
2016-02-02 09:57:40 -0800 (Tue, 02 Feb 2016)

Log Message

CSP: Support checking content security policy without a script execution context
https://bugs.webkit.org/show_bug.cgi?id=153748
<rdar://problem/24439149>

Reviewed by Darin Alder.

Towards checking a Web Worker's content security policy against a redirected worker
script load or redirected XHR request for an XHR request initiated from it, we should
support instantiating a ContentSecurityPolicy object without a ScriptExecutionContext.

No functionality was changed. So, no new tests.

* dom/Document.cpp:
(WebCore::Document::initSecurityContext): Pass |this| as a reference instead of as a pointer.
* page/csp/ContentSecurityPolicy.cpp: Remove extraneous includes ScriptState.h, TextEncoding.h,
and URL.h as they are included by ContentSecurityPolicy.h, FormDataList.h and FormData.h, respectively.
(WebCore::CSPSource::CSPSource): Take a constant reference to a ContentSecurityPolicy instead
of a pointer since we never expected a null pointer.
(WebCore::CSPSource::schemeMatches): Move logic for checking the protocol of source "self"
from here to ContentSecurityPolicy::protocolMatchesSelf() because we may not have a security
origin if ContentSecurityPolicy was initiated without a ScriptExecutionContext object.
(WebCore::CSPSourceList::allowSelf): Added.
(WebCore::CSPSourceList::CSPSourceList): Take a constant reference to a ContentSecurityPolicy
instead of a pointer since we never expected a null pointer. Remove fields from member
initialization list that can be initialized using C++11 in-class initialization syntax.
(WebCore::CSPSourceList::matches): Call ContentSecurityPolicy::urlMatchesSelf() to match the
effective URL against the URL of source "self".
(WebCore::CSPSourceList::parse): Update code as necessary now that m_policy is a reference
instead of a pointer.
(WebCore::CSPSourceList::parseSource): Simplify code by setting internal member fields directly
instead of via member functions.
(WebCore::CSPSourceList::parsePath): Update code as necessary now that m_policy is a reference
instead of a pointer.
(WebCore::CSPDirective::CSPDirective): Take a constant reference to a ContentSecurityPolicy
instead of a pointer since we never expected a null pointer.
(WebCore::CSPDirective::policy): Return a reference to a const ContentSecurityPolicy.
(WebCore::MediaListDirective::MediaListDirective): Take a constant reference to a ContentSecurityPolicy
instead of a pointer since we never expected a null pointer.
(WebCore::MediaListDirective::parse): Update code as necessary now that m_policy is a reference
instead of a pointer.
(WebCore::SourceListDirective::SourceListDirective): Take a constant reference to a ContentSecurityPolicy
instead of a pointer since we never expected a null pointer.
(WebCore::SourceListDirective::allows): Write in terms of CSPSourceList::allowSelf() because we
may not have a security origin to get a URL from if ContentSecurityPolicy was initiated without
a ScriptExecutionContext object.
(WebCore::CSPDirectiveList::reportURIs): Change return type from Vector<URL> to Vector<String>
The caller will convert the strings to URLs with respect to the script execution context.
(WebCore::CSPDirectiveList::parseReportURI): Store the report URI as a string instead of a URL
because we may not have a security origin to compute the absolute URL if ContentSecurityPolicy
was initiated without a ScriptExecutionContext object.
(WebCore::CSPDirectiveList::CSPDirectiveList): Take a reference to a ContentSecurityPolicy
instead of a pointer since we never expected a null pointer. It would be better to take a const
reference to a ContentSecurityPolicy, but ContentSecurityPolicy::applySandboxPolicy() needs to set
state on ContentSecurityPolicy :(
(WebCore::CSPDirectiveList::create): Ditto.
(WebCore::CSPDirectiveList::reportViolation): Update code as necessary now that m_policy is a reference
instead of a pointer.
(WebCore::CSPDirectiveList::checkEvalAndReportViolation): Ditto.
(WebCore::CSPDirectiveList::checkInlineAndReportViolation): Ditto.
(WebCore::CSPDirectiveList::parseDirective): Ditto.
(WebCore::CSPDirectiveList::parseReportURI): Store the report URI as a string instead of a URL
because we may not have a security origin to compute the absolute URL if ContentSecurityPolicy
was initiated without a ScriptExecutionContext object.
(WebCore::CSPDirectiveList::setCSPDirective): Update code as necessary now that m_policy is a reference
instead of a pointer.
(WebCore::CSPDirectiveList::applySandboxPolicy): Ditto.
(WebCore::CSPDirectiveList::parseReflectedXSS): Ditto.
(WebCore::CSPDirectiveList::addDirective): Ditto.
(WebCore::ContentSecurityPolicy::ContentSecurityPolicy): Modified to take the ScriptExecutionObject
as a reference and compute the CSPSource object for "self" and cache the protocol for "self". Removed
field m_overrideInlineStyleAllowed from the member initialization list and used C++11 in-class
initialization syntax to initialize it. Added overloaded constructor that takes a SecurityOrigin object.
We are not making use of this overloaded constructor at this time. We will in a subsequent patch.
(WebCore::ContentSecurityPolicy::didReceiveHeader): Store the eval disabled error message for
the last parsed policy in a member field instead of using it as part of disabling eval execution
on the script execution context because we may not have such a context.
(WebCore::ContentSecurityPolicy::applyPolicyToScriptExecutionContext): Applies the content security
policy eval and sandbox restrictions to the script execution context.
(WebCore::ContentSecurityPolicy::urlMatchesSelf): Match the specified URL against the URL for
source "self".
(WebCore::ContentSecurityPolicy::protocolMatchesSelf): Match the protocol of the specified URL
against the protocol for source "self".
(WebCore::ContentSecurityPolicy::gatherReportURIs): Modified to use the script execution context
to compute the absolute URL for each report URI.
(WebCore::ContentSecurityPolicy::reportViolation): Bail out if we do not have a script execution
context.
(WebCore::ContentSecurityPolicy::logToConsole): Only log to the console if we have a script
execution context.
(WebCore::ContentSecurityPolicy::reportBlockedScriptExecutionToInspector): Only report blocked
script execution to the Web Inspector if we have a script execution context.
(WebCore::CSPSourceList::addSourceSelf): Deleted.
(WebCore::CSPSourceList::addSourceStar): Deleted.
(WebCore::CSPSourceList::addSourceUnsafeInline): Deleted.
(WebCore::CSPSourceList::addSourceUnsafeEval): Deleted.
(WebCore::CSPDirectiveList::gatherReportURIs): Deleted.
(WebCore::ContentSecurityPolicy::securityOrigin): Deleted.
(WebCore::ContentSecurityPolicy::url): Deleted.
(WebCore::ContentSecurityPolicy::completeURL): Deleted.
(WebCore::ContentSecurityPolicy::enforceSandboxFlags): Deleted.
* page/csp/ContentSecurityPolicy.h:
(WebCore::ContentSecurityPolicy::enforceSandboxFlags): Accumulates the parsed sandbox flags. We
will apply the sandbox flags in ContentSecurityPolicy::applyPolicyToScriptExecutionContext().
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::WorkerGlobalScope): Instantiate ContentSecurityPolicy.
(WebCore::WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders): Move instantiation of
ContentSecurityPolicy from here to constructor.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (196011 => 196012)


--- trunk/Source/WebCore/ChangeLog	2016-02-02 16:58:41 UTC (rev 196011)
+++ trunk/Source/WebCore/ChangeLog	2016-02-02 17:57:40 UTC (rev 196012)
@@ -1,3 +1,112 @@
+2016-02-02  Daniel Bates  <[email protected]>
+
+        CSP: Support checking content security policy without a script execution context
+        https://bugs.webkit.org/show_bug.cgi?id=153748
+        <rdar://problem/24439149>
+
+        Reviewed by Darin Alder.
+
+        Towards checking a Web Worker's content security policy against a redirected worker
+        script load or redirected XHR request for an XHR request initiated from it, we should
+        support instantiating a ContentSecurityPolicy object without a ScriptExecutionContext.
+
+        No functionality was changed. So, no new tests.
+
+        * dom/Document.cpp:
+        (WebCore::Document::initSecurityContext): Pass |this| as a reference instead of as a pointer.
+        * page/csp/ContentSecurityPolicy.cpp: Remove extraneous includes ScriptState.h, TextEncoding.h,
+        and URL.h as they are included by ContentSecurityPolicy.h, FormDataList.h and FormData.h, respectively.
+        (WebCore::CSPSource::CSPSource): Take a constant reference to a ContentSecurityPolicy instead
+        of a pointer since we never expected a null pointer.
+        (WebCore::CSPSource::schemeMatches): Move logic for checking the protocol of source "self"
+        from here to ContentSecurityPolicy::protocolMatchesSelf() because we may not have a security
+        origin if ContentSecurityPolicy was initiated without a ScriptExecutionContext object.
+        (WebCore::CSPSourceList::allowSelf): Added.
+        (WebCore::CSPSourceList::CSPSourceList): Take a constant reference to a ContentSecurityPolicy
+        instead of a pointer since we never expected a null pointer. Remove fields from member
+        initialization list that can be initialized using C++11 in-class initialization syntax.
+        (WebCore::CSPSourceList::matches): Call ContentSecurityPolicy::urlMatchesSelf() to match the
+        effective URL against the URL of source "self".
+        (WebCore::CSPSourceList::parse): Update code as necessary now that m_policy is a reference
+        instead of a pointer.
+        (WebCore::CSPSourceList::parseSource): Simplify code by setting internal member fields directly
+        instead of via member functions.
+        (WebCore::CSPSourceList::parsePath): Update code as necessary now that m_policy is a reference
+        instead of a pointer.
+        (WebCore::CSPDirective::CSPDirective): Take a constant reference to a ContentSecurityPolicy
+        instead of a pointer since we never expected a null pointer.
+        (WebCore::CSPDirective::policy): Return a reference to a const ContentSecurityPolicy.
+        (WebCore::MediaListDirective::MediaListDirective): Take a constant reference to a ContentSecurityPolicy
+        instead of a pointer since we never expected a null pointer.
+        (WebCore::MediaListDirective::parse): Update code as necessary now that m_policy is a reference
+        instead of a pointer.
+        (WebCore::SourceListDirective::SourceListDirective): Take a constant reference to a ContentSecurityPolicy
+        instead of a pointer since we never expected a null pointer.
+        (WebCore::SourceListDirective::allows): Write in terms of CSPSourceList::allowSelf() because we
+        may not have a security origin to get a URL from if ContentSecurityPolicy was initiated without
+        a ScriptExecutionContext object.
+        (WebCore::CSPDirectiveList::reportURIs): Change return type from Vector<URL> to Vector<String>
+        The caller will convert the strings to URLs with respect to the script execution context.
+        (WebCore::CSPDirectiveList::parseReportURI): Store the report URI as a string instead of a URL
+        because we may not have a security origin to compute the absolute URL if ContentSecurityPolicy
+        was initiated without a ScriptExecutionContext object.
+        (WebCore::CSPDirectiveList::CSPDirectiveList): Take a reference to a ContentSecurityPolicy
+        instead of a pointer since we never expected a null pointer. It would be better to take a const
+        reference to a ContentSecurityPolicy, but ContentSecurityPolicy::applySandboxPolicy() needs to set
+        state on ContentSecurityPolicy :(
+        (WebCore::CSPDirectiveList::create): Ditto.
+        (WebCore::CSPDirectiveList::reportViolation): Update code as necessary now that m_policy is a reference
+        instead of a pointer.
+        (WebCore::CSPDirectiveList::checkEvalAndReportViolation): Ditto.
+        (WebCore::CSPDirectiveList::checkInlineAndReportViolation): Ditto.
+        (WebCore::CSPDirectiveList::parseDirective): Ditto.
+        (WebCore::CSPDirectiveList::parseReportURI): Store the report URI as a string instead of a URL
+        because we may not have a security origin to compute the absolute URL if ContentSecurityPolicy
+        was initiated without a ScriptExecutionContext object.
+        (WebCore::CSPDirectiveList::setCSPDirective): Update code as necessary now that m_policy is a reference
+        instead of a pointer.
+        (WebCore::CSPDirectiveList::applySandboxPolicy): Ditto.
+        (WebCore::CSPDirectiveList::parseReflectedXSS): Ditto.
+        (WebCore::CSPDirectiveList::addDirective): Ditto.
+        (WebCore::ContentSecurityPolicy::ContentSecurityPolicy): Modified to take the ScriptExecutionObject
+        as a reference and compute the CSPSource object for "self" and cache the protocol for "self". Removed
+        field m_overrideInlineStyleAllowed from the member initialization list and used C++11 in-class
+        initialization syntax to initialize it. Added overloaded constructor that takes a SecurityOrigin object.
+        We are not making use of this overloaded constructor at this time. We will in a subsequent patch.
+        (WebCore::ContentSecurityPolicy::didReceiveHeader): Store the eval disabled error message for
+        the last parsed policy in a member field instead of using it as part of disabling eval execution
+        on the script execution context because we may not have such a context.
+        (WebCore::ContentSecurityPolicy::applyPolicyToScriptExecutionContext): Applies the content security
+        policy eval and sandbox restrictions to the script execution context.
+        (WebCore::ContentSecurityPolicy::urlMatchesSelf): Match the specified URL against the URL for
+        source "self".
+        (WebCore::ContentSecurityPolicy::protocolMatchesSelf): Match the protocol of the specified URL
+        against the protocol for source "self".
+        (WebCore::ContentSecurityPolicy::gatherReportURIs): Modified to use the script execution context
+        to compute the absolute URL for each report URI.
+        (WebCore::ContentSecurityPolicy::reportViolation): Bail out if we do not have a script execution
+        context.
+        (WebCore::ContentSecurityPolicy::logToConsole): Only log to the console if we have a script
+        execution context.
+        (WebCore::ContentSecurityPolicy::reportBlockedScriptExecutionToInspector): Only report blocked
+        script execution to the Web Inspector if we have a script execution context.
+        (WebCore::CSPSourceList::addSourceSelf): Deleted.
+        (WebCore::CSPSourceList::addSourceStar): Deleted.
+        (WebCore::CSPSourceList::addSourceUnsafeInline): Deleted.
+        (WebCore::CSPSourceList::addSourceUnsafeEval): Deleted.
+        (WebCore::CSPDirectiveList::gatherReportURIs): Deleted.
+        (WebCore::ContentSecurityPolicy::securityOrigin): Deleted.
+        (WebCore::ContentSecurityPolicy::url): Deleted.
+        (WebCore::ContentSecurityPolicy::completeURL): Deleted.
+        (WebCore::ContentSecurityPolicy::enforceSandboxFlags): Deleted.
+        * page/csp/ContentSecurityPolicy.h:
+        (WebCore::ContentSecurityPolicy::enforceSandboxFlags): Accumulates the parsed sandbox flags. We
+        will apply the sandbox flags in ContentSecurityPolicy::applyPolicyToScriptExecutionContext().
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::WorkerGlobalScope): Instantiate ContentSecurityPolicy.
+        (WebCore::WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders): Move instantiation of
+        ContentSecurityPolicy from here to constructor.
+
 2016-02-02  Eric Carlson  <[email protected]>
 
         Allow ports to disable automatic text track selection

Modified: trunk/Source/WebCore/dom/Document.cpp (196011 => 196012)


--- trunk/Source/WebCore/dom/Document.cpp	2016-02-02 16:58:41 UTC (rev 196011)
+++ trunk/Source/WebCore/dom/Document.cpp	2016-02-02 17:57:40 UTC (rev 196012)
@@ -5128,7 +5128,7 @@
         // This can occur via document.implementation.createDocument().
         setCookieURL(URL(ParsedURLString, emptyString()));
         setSecurityOriginPolicy(SecurityOriginPolicy::create(SecurityOrigin::createUnique()));
-        setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(this));
+        setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(*this));
         return;
     }
 
@@ -5141,7 +5141,7 @@
         applyContentDispositionAttachmentSandbox();
 
     setSecurityOriginPolicy(SecurityOriginPolicy::create(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url)));
-    setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(this));
+    setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(*this));
 
     if (Settings* settings = this->settings()) {
         if (!settings->webSecurityEnabled()) {

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp (196011 => 196012)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp	2016-02-02 16:58:41 UTC (rev 196011)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp	2016-02-02 17:57:40 UTC (rev 196012)
@@ -38,11 +38,8 @@
 #include "RuntimeEnabledFeatures.h"
 #include "SchemeRegistry.h"
 #include "ScriptController.h"
-#include "ScriptState.h"
 #include "SecurityOrigin.h"
 #include "SecurityPolicyViolationEvent.h"
-#include "TextEncoding.h"
-#include "URL.h"
 #include <inspector/InspectorValues.h>
 #include <inspector/ScriptCallStack.h>
 #include <inspector/ScriptCallStackFactory.h>
@@ -215,7 +212,7 @@
 
 class CSPSource {
 public:
-    CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
+    CSPSource(const ContentSecurityPolicy& policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
         : m_policy(policy)
         , m_scheme(scheme)
         , m_host(host)
@@ -238,14 +235,8 @@
 private:
     bool schemeMatches(const URL& url) const
     {
-        if (m_scheme.isEmpty()) {
-            String protectedResourceScheme(m_policy->securityOrigin()->protocol());
-#if ENABLE(CSP_NEXT)
-            if (equalLettersIgnoringASCIICase(protectedResourceScheme, "http"))
-                return url.protocolIsInHTTPFamily();
-#endif
-            return equalIgnoringASCIICase(url.protocol(), protectedResourceScheme);
-        }
+        if (m_scheme.isEmpty())
+            return m_policy.protocolMatchesSelf(url);
         return equalIgnoringASCIICase(url.protocol(), m_scheme);
     }
 
@@ -292,7 +283,7 @@
 
     bool isSchemeOnly() const { return m_host.isEmpty(); }
 
-    ContentSecurityPolicy* m_policy;
+    const ContentSecurityPolicy& m_policy;
     String m_scheme;
     String m_host;
     int m_port;
@@ -304,12 +295,13 @@
 
 class CSPSourceList {
 public:
-    CSPSourceList(ContentSecurityPolicy*, const String& directiveName);
+    CSPSourceList(const ContentSecurityPolicy&, const String& directiveName);
 
     void parse(const String&);
     bool matches(const URL&);
     bool allowInline() const { return m_allowInline; }
     bool allowEval() const { return m_allowEval; }
+    bool allowSelf() const { return m_allowSelf; }
 
 private:
     void parse(const UChar* begin, const UChar* end);
@@ -320,25 +312,18 @@
     bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
     bool parsePath(const UChar* begin, const UChar* end, String& path);
 
-    void addSourceSelf();
-    void addSourceStar();
-    void addSourceUnsafeInline();
-    void addSourceUnsafeEval();
-
-    ContentSecurityPolicy* m_policy;
+    const ContentSecurityPolicy& m_policy;
     Vector<CSPSource> m_list;
     String m_directiveName;
-    bool m_allowStar;
-    bool m_allowInline;
-    bool m_allowEval;
+    bool m_allowSelf { false };
+    bool m_allowStar { false };
+    bool m_allowInline { false };
+    bool m_allowEval { false };
 };
 
-CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& directiveName)
+CSPSourceList::CSPSourceList(const ContentSecurityPolicy& policy, const String& directiveName)
     : m_policy(policy)
     , m_directiveName(directiveName)
-    , m_allowStar(false)
-    , m_allowInline(false)
-    , m_allowEval(false)
 {
 }
 
@@ -358,6 +343,9 @@
 
     URL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;
 
+    if (m_allowSelf && m_policy.urlMatchesSelf(effectiveURL))
+        return true;
+
     for (auto& entry : m_list) {
         if (entry.matches(effectiveURL))
             return true;
@@ -393,10 +381,10 @@
             if (scheme.isEmpty() && host.isEmpty())
                 continue;
             if (isDirectiveName(host))
-                m_policy->reportDirectiveAsSourceExpression(m_directiveName, host);
+                m_policy.reportDirectiveAsSourceExpression(m_directiveName, host);
             m_list.append(CSPSource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard));
         } else
-            m_policy->reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
+            m_policy.reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
 
         ASSERT(position == end || isASCIISpace(*position));
      }
@@ -415,22 +403,22 @@
         return false;
 
     if (end - begin == 1 && *begin == '*') {
-        addSourceStar();
+        m_allowStar = true;
         return true;
     }
 
     if (equalLettersIgnoringASCIICase(begin, end - begin, "'self'")) {
-        addSourceSelf();
+        m_allowSelf = true;
         return true;
     }
 
     if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-inline'")) {
-        addSourceUnsafeInline();
+        m_allowInline = true;
         return true;
     }
 
     if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-eval'")) {
-        addSourceUnsafeEval();
+        m_allowEval = true;
         return true;
     }
 
@@ -590,7 +578,7 @@
     // path/to/file.js?query=string || path/to/file.js#anchor
     //                ^                               ^
     if (position < end)
-        m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
+        m_policy.reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
 
     path = decodeURLEscapeSequences(String(begin, position - begin));
 
@@ -630,29 +618,9 @@
     return ok;
 }
 
-void CSPSourceList::addSourceSelf()
-{
-    m_list.append(CSPSource(m_policy, m_policy->securityOrigin()->protocol(), m_policy->securityOrigin()->host(), m_policy->securityOrigin()->port(), String(), false, false));
-}
-
-void CSPSourceList::addSourceStar()
-{
-    m_allowStar = true;
-}
-
-void CSPSourceList::addSourceUnsafeInline()
-{
-    m_allowInline = true;
-}
-
-void CSPSourceList::addSourceUnsafeEval()
-{
-    m_allowEval = true;
-}
-
 class CSPDirective {
 public:
-    CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+    CSPDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
         : m_name(name)
         , m_text(name + ' ' + value)
         , m_policy(policy)
@@ -662,17 +630,17 @@
     const String& text() const { return m_text; }
 
 protected:
-    const ContentSecurityPolicy* policy() const { return m_policy; }
+    const ContentSecurityPolicy& policy() const { return m_policy; }
 
 private:
     String m_name;
     String m_text;
-    ContentSecurityPolicy* m_policy;
+    const ContentSecurityPolicy& m_policy;
 };
 
 class MediaListDirective : public CSPDirective {
 public:
-    MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+    MediaListDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
         : CSPDirective(name, value, policy)
     {
         parse(value);
@@ -693,7 +661,7 @@
 
         // 'plugin-types ____;' OR 'plugin-types;'
         if (value.isEmpty()) {
-            policy()->reportInvalidPluginTypes(value);
+            policy().reportInvalidPluginTypes(value);
             return;
         }
 
@@ -709,7 +677,7 @@
             begin = position;
             if (!skipExactly<isMediaTypeCharacter>(position, end)) {
                 skipWhile<isNotASCIISpace>(position, end);
-                policy()->reportInvalidPluginTypes(String(begin, position - begin));
+                policy().reportInvalidPluginTypes(String(begin, position - begin));
                 continue;
             }
             skipWhile<isMediaTypeCharacter>(position, end);
@@ -718,7 +686,7 @@
             //      ^
             if (!skipExactly(position, end, '/')) {
                 skipWhile<isNotASCIISpace>(position, end);
-                policy()->reportInvalidPluginTypes(String(begin, position - begin));
+                policy().reportInvalidPluginTypes(String(begin, position - begin));
                 continue;
             }
 
@@ -726,7 +694,7 @@
             //       ^
             if (!skipExactly<isMediaTypeCharacter>(position, end)) {
                 skipWhile<isNotASCIISpace>(position, end);
-                policy()->reportInvalidPluginTypes(String(begin, position - begin));
+                policy().reportInvalidPluginTypes(String(begin, position - begin));
                 continue;
             }
             skipWhile<isMediaTypeCharacter>(position, end);
@@ -735,7 +703,7 @@
             //            ^                          ^               ^
             if (position < end && isNotASCIISpace(*position)) {
                 skipWhile<isNotASCIISpace>(position, end);
-                policy()->reportInvalidPluginTypes(String(begin, position - begin));
+                policy().reportInvalidPluginTypes(String(begin, position - begin));
                 continue;
             }
             m_pluginTypes.add(String(begin, position - begin));
@@ -749,7 +717,7 @@
 
 class SourceListDirective : public CSPDirective {
 public:
-    SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+    SourceListDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
         : CSPDirective(name, value, policy)
         , m_sourceList(policy, name)
     {
@@ -758,7 +726,10 @@
 
     bool allows(const URL& url)
     {
-        return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
+        // FIXME: We should investigate returning false for an empty URL.
+        if (url.isEmpty())
+            return m_sourceList.allowSelf();
+        return m_sourceList.matches(url);
     }
 
     bool allowInline() const { return m_sourceList.allowInline(); }
@@ -771,8 +742,8 @@
 class CSPDirectiveList {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static std::unique_ptr<CSPDirectiveList> create(ContentSecurityPolicy*, const String&, ContentSecurityPolicyHeaderType);
-    CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicyHeaderType);
+    static std::unique_ptr<CSPDirectiveList> create(ContentSecurityPolicy&, const String&, ContentSecurityPolicyHeaderType);
+    CSPDirectiveList(ContentSecurityPolicy&, ContentSecurityPolicyHeaderType);
 
     const String& header() const { return m_header; }
     ContentSecurityPolicyHeaderType headerType() const { return m_headerType; }
@@ -795,11 +766,10 @@
     bool allowFormAction(const URL&, ContentSecurityPolicy::ReportingStatus) const;
     bool allowBaseURI(const URL&, ContentSecurityPolicy::ReportingStatus) const;
 
-    void gatherReportURIs(DOMStringList&) const;
     const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
     ContentSecurityPolicy::ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
     bool isReportOnly() const { return m_reportOnly; }
-    const Vector<URL>& reportURIs() const { return m_reportURIs; }
+    const Vector<String>& reportURIs() const { return m_reportURIs; }
 
 private:
     void parse(const String&);
@@ -832,7 +802,8 @@
 
     bool denyIfEnforcingPolicy() const { return m_reportOnly; }
 
-    ContentSecurityPolicy* m_policy;
+    // FIXME: Make this a const reference once we teach applySandboxPolicy() to store its policy as opposed to applying it directly onto ContentSecurityPolicy.
+    ContentSecurityPolicy& m_policy;
 
     String m_header;
     ContentSecurityPolicyHeaderType m_headerType;
@@ -854,12 +825,12 @@
     std::unique_ptr<SourceListDirective> m_scriptSrc;
     std::unique_ptr<SourceListDirective> m_styleSrc;
 
-    Vector<URL> m_reportURIs;
+    Vector<String> m_reportURIs;
 
     String m_evalDisabledErrorMessage;
 };
 
-CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicyHeaderType type)
+CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy& policy, ContentSecurityPolicyHeaderType type)
     : m_policy(policy)
     , m_headerType(type)
     , m_reportOnly(false)
@@ -869,7 +840,7 @@
     m_reportOnly = (type == ContentSecurityPolicyHeaderType::Report || type == ContentSecurityPolicyHeaderType::PrefixedReport);
 }
 
-std::unique_ptr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const String& header, ContentSecurityPolicyHeaderType type)
+std::unique_ptr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy& policy, const String& header, ContentSecurityPolicyHeaderType type)
 {
     auto directives = std::make_unique<CSPDirectiveList>(policy, type);
     directives->parse(header);
@@ -880,7 +851,7 @@
     }
 
     if (directives->isReportOnly() && directives->reportURIs().isEmpty())
-        policy->reportMissingReportURI(header);
+        policy.reportMissingReportURI(header);
 
     return directives;
 }
@@ -888,7 +859,7 @@
 void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
 {
     String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
-    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state);
+    m_policy.reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state);
 }
 
 bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
@@ -931,7 +902,7 @@
 
     reportViolation(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", URL(), contextURL, contextLine, state);
     if (!m_reportOnly) {
-        m_policy->reportBlockedScriptExecutionToInspector(directive->text());
+        m_policy.reportBlockedScriptExecutionToInspector(directive->text());
         return false;
     }
     return true;
@@ -963,7 +934,7 @@
 
     if (!m_reportOnly) {
         if (isScript)
-            m_policy->reportBlockedScriptExecutionToInspector(directive->text());
+            m_policy.reportBlockedScriptExecutionToInspector(directive->text());
         return false;
     }
     return true;
@@ -1113,12 +1084,6 @@
         (m_reportOnly || checkSource(operativeDirective(m_connectSrc.get()), url));
 }
 
-void CSPDirectiveList::gatherReportURIs(DOMStringList& list) const
-{
-    for (auto& uri : m_reportURIs)
-        list.append(uri.string());
-}
-
 bool CSPDirectiveList::allowFormAction(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
 {
     return reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport ?
@@ -1183,7 +1148,7 @@
     // The directive-name must be non-empty.
     if (nameBegin == position) {
         skipWhile<isNotASCIISpace>(position, end);
-        m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
+        m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin));
         return false;
     }
 
@@ -1194,7 +1159,7 @@
 
     if (!skipExactly<isASCIISpace>(position, end)) {
         skipWhile<isNotASCIISpace>(position, end);
-        m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
+        m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin));
         return false;
     }
 
@@ -1204,7 +1169,7 @@
     skipWhile<isDirectiveValueCharacter>(position, end);
 
     if (position != end) {
-        m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
+        m_policy.reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
         return false;
     }
 
@@ -1219,7 +1184,7 @@
 void CSPDirectiveList::parseReportURI(const String& name, const String& value)
 {
     if (!m_reportURIs.isEmpty()) {
-        m_policy->reportDuplicateDirective(name);
+        m_policy.reportDuplicateDirective(name);
         return;
     }
 
@@ -1233,10 +1198,8 @@
         const UChar* urlBegin = position;
         skipWhile<isNotASCIISpace>(position, end);
 
-        if (urlBegin < position) {
-            String url = "" position - urlBegin);
-            m_reportURIs.append(m_policy->completeURL(url));
-        }
+        if (urlBegin < position)
+            m_reportURIs.append(value.substring(urlBegin - characters, position - urlBegin));
     }
 }
 
@@ -1245,7 +1208,7 @@
 void CSPDirectiveList::setCSPDirective(const String& name, const String& value, std::unique_ptr<CSPDirectiveType>& directive)
 {
     if (directive) {
-        m_policy->reportDuplicateDirective(name);
+        m_policy.reportDuplicateDirective(name);
         return;
     }
     directive = std::make_unique<CSPDirectiveType>(name, value, m_policy);
@@ -1254,27 +1217,27 @@
 void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
 {
     if (m_haveSandboxPolicy) {
-        m_policy->reportDuplicateDirective(name);
+        m_policy.reportDuplicateDirective(name);
         return;
     }
     m_haveSandboxPolicy = true;
     String invalidTokens;
-    m_policy->enforceSandboxFlags(SecurityContext::parseSandboxPolicy(sandboxPolicy, invalidTokens));
+    m_policy.enforceSandboxFlags(SecurityContext::parseSandboxPolicy(sandboxPolicy, invalidTokens));
     if (!invalidTokens.isNull())
-        m_policy->reportInvalidSandboxFlags(invalidTokens);
+        m_policy.reportInvalidSandboxFlags(invalidTokens);
 }
 
 void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
 {
     if (m_reflectedXSSDisposition != ContentSecurityPolicy::ReflectedXSSUnset) {
-        m_policy->reportDuplicateDirective(name);
+        m_policy.reportDuplicateDirective(name);
         m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
         return;
     }
 
     if (value.isEmpty()) {
         m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
-        m_policy->reportInvalidReflectedXSS(value);
+        m_policy.reportInvalidReflectedXSS(value);
         return;
     }
 
@@ -1296,7 +1259,7 @@
         m_reflectedXSSDisposition = ContentSecurityPolicy::BlockReflectedXSS;
     else {
         m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
-        m_policy->reportInvalidReflectedXSS(value);
+        m_policy.reportInvalidReflectedXSS(value);
         return;
     }
 
@@ -1307,7 +1270,7 @@
     // value1 value2
     //        ^
     m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
-    m_policy->reportInvalidReflectedXSS(value);
+    m_policy.reportInvalidReflectedXSS(value);
 }
 
 void CSPDirectiveList::addDirective(const String& name, const String& value)
@@ -1337,7 +1300,7 @@
     else if (equalLettersIgnoringASCIICase(name, reportURI))
         parseReportURI(name, value);
 #if ENABLE(CSP_NEXT)
-    else if (m_policy->experimentalFeaturesEnabled()) {
+    else if (m_policy.experimentalFeaturesEnabled()) {
         if (equalLettersIgnoringASCIICase(name, baseURI))
             setCSPDirective<SourceListDirective>(name, value, m_baseURI);
         else if (equalLettersIgnoringASCIICase(name, formAction))
@@ -1347,19 +1310,30 @@
         else if (equalLettersIgnoringASCIICase(name, reflectedXSS))
             parseReflectedXSS(name, value);
         else
-            m_policy->reportUnsupportedDirective(name);
+            m_policy.reportUnsupportedDirective(name);
     }
 #endif
     else
-        m_policy->reportUnsupportedDirective(name);
+        m_policy.reportUnsupportedDirective(name);
 }
 
-ContentSecurityPolicy::ContentSecurityPolicy(ScriptExecutionContext* scriptExecutionContext)
-    : m_scriptExecutionContext(scriptExecutionContext)
-    , m_overrideInlineStyleAllowed(false)
+ContentSecurityPolicy::ContentSecurityPolicy(ScriptExecutionContext& scriptExecutionContext)
+    : m_scriptExecutionContext(&scriptExecutionContext)
+    , m_sandboxFlags(SandboxNone)
 {
+    ASSERT(scriptExecutionContext.securityOrigin());
+    auto& securityOrigin = *scriptExecutionContext.securityOrigin();
+    m_selfSourceProtocol = securityOrigin.protocol();
+    m_selfSource = std::make_unique<CSPSource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false);
 }
 
+ContentSecurityPolicy::ContentSecurityPolicy(const SecurityOrigin& securityOrigin)
+    : m_sandboxFlags(SandboxNone)
+{
+    m_selfSourceProtocol = securityOrigin.protocol();
+    m_selfSource = std::make_unique<CSPSource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false);
+}
+
 ContentSecurityPolicy::~ContentSecurityPolicy()
 {
 }
@@ -1400,9 +1374,9 @@
 
         // header1,header2 OR header1
         //        ^                  ^
-        std::unique_ptr<CSPDirectiveList> policy = CSPDirectiveList::create(this, String(begin, position - begin), type);
+        std::unique_ptr<CSPDirectiveList> policy = CSPDirectiveList::create(*this, String(begin, position - begin), type);
         if (!policy->allowEval(0, ContentSecurityPolicy::ReportingStatus::SuppressReport))
-            m_scriptExecutionContext->disableEval(policy->evalDisabledErrorMessage());
+            m_lastPolicyEvalDisabledErrorMessage = policy->evalDisabledErrorMessage();
 
         m_policies.append(policy.release());
 
@@ -1411,13 +1385,39 @@
         skipExactly(position, end, ',');
         begin = position;
     }
+
+    if (m_scriptExecutionContext)
+        applyPolicyToScriptExecutionContext();
 }
 
+void ContentSecurityPolicy::applyPolicyToScriptExecutionContext()
+{
+    ASSERT(m_scriptExecutionContext);
+    if (!m_lastPolicyEvalDisabledErrorMessage.isNull())
+        m_scriptExecutionContext->disableEval(m_lastPolicyEvalDisabledErrorMessage);
+    if (m_sandboxFlags != SandboxNone && is<Document>(m_scriptExecutionContext))
+        m_scriptExecutionContext->enforceSandboxFlags(m_sandboxFlags);
+}
+
 void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
 {
     m_overrideInlineStyleAllowed = value;
 }
 
+bool ContentSecurityPolicy::urlMatchesSelf(const URL& url) const
+{
+    return m_selfSource->matches(url);
+}
+
+bool ContentSecurityPolicy::protocolMatchesSelf(const URL& url) const
+{
+#if ENABLE(CSP_NEXT)
+    if (equalLettersIgnoringASCIICase(m_selfSourceProtocol, "http"))
+        return url.protocolIsInHTTPFamily();
+#endif
+    return equalIgnoringASCIICase(url.protocol(), m_selfSourceProtocol);
+}
+
 template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
 bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
 {
@@ -1573,30 +1573,13 @@
 
 void ContentSecurityPolicy::gatherReportURIs(DOMStringList& list) const
 {
-    for (auto& policy : m_policies)
-        policy->gatherReportURIs(list);
+    ASSERT(m_scriptExecutionContext);
+    for (auto& policy : m_policies) {
+        for (auto& url : policy->reportURIs())
+            list.append(m_scriptExecutionContext->completeURL(url).string());
+    }
 }
 
-SecurityOrigin* ContentSecurityPolicy::securityOrigin() const
-{
-    return m_scriptExecutionContext->securityOrigin();
-}
-
-const URL& ContentSecurityPolicy::url() const
-{
-    return m_scriptExecutionContext->url();
-}
-
-URL ContentSecurityPolicy::completeURL(const String& url) const
-{
-    return m_scriptExecutionContext->completeURL(url);
-}
-
-void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) const
-{
-    m_scriptExecutionContext->enforceSandboxFlags(mask);
-}
-
 static String stripURLForUseInReport(Document& document, const URL& url)
 {
     if (!url.isValid())
@@ -1628,12 +1611,12 @@
 }
 #endif
 
-void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<URL>& reportURIs, const String& header, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
+void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<String>& reportURIs, const String& header, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
 {
     logToConsole(consoleMessage, contextURL, contextLine, state);
 
     // FIXME: Support sending reports from worker.
-    if (!is<Document>(*m_scriptExecutionContext))
+    if (!is<Document>(m_scriptExecutionContext))
         return;
 
     Document& document = downcast<Document>(*m_scriptExecutionContext);
@@ -1690,7 +1673,7 @@
     RefPtr<FormData> report = FormData::create(reportObject->toJSONString().utf8());
 
     for (const auto& url : reportURIs)
-        PingLoader::sendViolationReport(*frame, url, report.copyRef());
+        PingLoader::sendViolationReport(*frame, document.completeURL(url), report.copyRef());
 }
 
 void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const
@@ -1774,12 +1757,14 @@
 void ContentSecurityPolicy::logToConsole(const String& message, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
 {
     // FIXME: <http://webkit.org/b/114317> ContentSecurityPolicy::logToConsole should include a column number
-    m_scriptExecutionContext->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, contextURL, contextLine.oneBasedInt(), 0, state);
+    if (m_scriptExecutionContext)
+        m_scriptExecutionContext->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, contextURL, contextLine.oneBasedInt(), 0, state);
 }
 
 void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String& directiveText) const
 {
-    InspectorInstrumentation::scriptExecutionBlockedByCSP(m_scriptExecutionContext, directiveText);
+    if (m_scriptExecutionContext)
+        InspectorInstrumentation::scriptExecutionBlockedByCSP(m_scriptExecutionContext, directiveText);
 }
 
 bool ContentSecurityPolicy::experimentalFeaturesEnabled() const

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h (196011 => 196012)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h	2016-02-02 16:58:41 UTC (rev 196011)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h	2016-02-02 17:57:40 UTC (rev 196012)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011 Google, Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,13 +28,9 @@
 #define ContentSecurityPolicy_h
 
 #include "ContentSecurityPolicyResponseHeaders.h"
-#include "URL.h"
 #include "ScriptState.h"
-#include <memory>
-#include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 #include <wtf/text/TextPosition.h>
-#include <wtf/text/WTFString.h>
 
 namespace WTF {
 class OrdinalNumber;
@@ -42,26 +39,24 @@
 namespace WebCore {
 
 class CSPDirectiveList;
+class CSPSource;
 class DOMStringList;
 class ScriptExecutionContext;
 class SecurityOrigin;
+class URL;
 
+typedef Vector<std::unique_ptr<CSPDirectiveList>> CSPDirectiveListVector;
 typedef int SandboxFlags;
-typedef Vector<std::unique_ptr<CSPDirectiveList>> CSPDirectiveListVector;
 
 class ContentSecurityPolicy {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit ContentSecurityPolicy(ScriptExecutionContext*);
+    explicit ContentSecurityPolicy(ScriptExecutionContext&);
+    explicit ContentSecurityPolicy(const SecurityOrigin&);
     ~ContentSecurityPolicy();
 
     void copyStateFrom(const ContentSecurityPolicy*);
 
-    enum class ReportingStatus {
-        SendReport,
-        SuppressReport
-    };
-
     // Be sure to update the behavior of XSSAuditor::combineXSSProtectionHeaderAndCSP whenever you change this enum's content or ordering.
     enum ReflectedXSSDisposition {
         ReflectedXSSUnset = 0,
@@ -70,18 +65,22 @@
         FilterReflectedXSS,
         BlockReflectedXSS
     };
+    ReflectedXSSDisposition reflectedXSSDisposition() const;
 
     ContentSecurityPolicyResponseHeaders responseHeaders() const;
     void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
     void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType);
 
+    enum class ReportingStatus {
+        SendReport,
+        SuppressReport
+    };
     bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowEval(JSC::ExecState* = nullptr, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowPluginType(const String& type, const String& typeAttribute, const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
-
     bool allowScriptFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowObjectFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowChildFrameFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
@@ -93,42 +92,57 @@
     bool allowFormAction(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowBaseURI(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
 
-    ReflectedXSSDisposition reflectedXSSDisposition() const;
-
     void setOverrideAllowInlineStyle(bool);
 
     bool isActive() const;
+
     void gatherReportURIs(DOMStringList&) const;
 
+    String evalDisabledErrorMessage() const;
+
+    bool experimentalFeaturesEnabled() const;
+
+    static bool shouldBypassMainWorldContentSecurityPolicy(ScriptExecutionContext&);
+
+    // The following functions are used by internal data structures to call back into this object when parsing, validating,
+    // and applying a Content Security Policy.
+    // FIXME: We should make the various directives serve only as state stores for the parsed policy and remove these functions.
+    // This class should traverse the directives, validating the policy, and applying it to the script execution context.
+
+    // Used by MediaListDirective
+    void reportInvalidPluginTypes(const String&) const;
+
+    // Used by CSPSourceList
     void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const;
+    void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
+    void reportInvalidSourceExpression(const String& directiveName, const String& source) const;
+    bool urlMatchesSelf(const URL&) const;
+
+    // Used by CSPDirectiveList
     void reportDuplicateDirective(const String&) const;
     void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const;
-    void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
-    void reportInvalidPluginTypes(const String&) const;
     void reportInvalidSandboxFlags(const String&) const;
-    void reportInvalidSourceExpression(const String& directiveName, const String& source) const;
     void reportInvalidReflectedXSS(const String&) const;
     void reportMissingReportURI(const String&) const;
     void reportUnsupportedDirective(const String&) const;
-    void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<URL>& reportURIs, const String& header, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
-
+    void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<String>& reportURIs, const String& header, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
     void reportBlockedScriptExecutionToInspector(const String& directiveText) const;
+    void enforceSandboxFlags(SandboxFlags sandboxFlags) { m_sandboxFlags |= sandboxFlags; }
 
-    const URL& url() const;
-    URL completeURL(const String&) const;
-    SecurityOrigin* securityOrigin() const;
-    void enforceSandboxFlags(SandboxFlags) const;
-    String evalDisabledErrorMessage() const;
+    // Used by CSPSource
+    bool protocolMatchesSelf(const URL&) const;
 
-    bool experimentalFeaturesEnabled() const;
-    static bool shouldBypassMainWorldContentSecurityPolicy(ScriptExecutionContext&);
-
 private:
     void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
+    void applyPolicyToScriptExecutionContext();
 
-    ScriptExecutionContext* m_scriptExecutionContext;
-    bool m_overrideInlineStyleAllowed;
+    ScriptExecutionContext* m_scriptExecutionContext { nullptr };
+    std::unique_ptr<CSPSource> m_selfSource;
+    String m_selfSourceProtocol;
     CSPDirectiveListVector m_policies;
+    String m_lastPolicyEvalDisabledErrorMessage;
+    SandboxFlags m_sandboxFlags;
+    bool m_overrideInlineStyleAllowed { false };
 };
 
 }

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (196011 => 196012)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2016-02-02 16:58:41 UTC (rev 196011)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2016-02-02 17:57:40 UTC (rev 196012)
@@ -72,6 +72,7 @@
     , m_topOrigin(topOrigin)
 {
     setSecurityOriginPolicy(SecurityOriginPolicy::create(SecurityOrigin::create(url)));
+    setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(*this));
 }
 
 WorkerGlobalScope::~WorkerGlobalScope()
@@ -87,7 +88,6 @@
 
 void WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders)
 {
-    setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(this));
     contentSecurityPolicy()->didReceiveHeaders(contentSecurityPolicyResponseHeaders);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to