Changeset 125817 in webkit


Ignore:
Timestamp:
Aug 16, 2012 3:44:07 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

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.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r125816 r125817  
     12012-08-16  Mike West  <mkwst@chromium.org>
     2
     3        Refactor CSPDirective to support non-sourcelist types.
     4        https://bugs.webkit.org/show_bug.cgi?id=94252
     5
     6        Reviewed by Adam Barth.
     7
     8        * http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt:
     9            This test was buggy. Now it writes out the full directive text as it
     10            ought to.
     11
    1122012-08-16  Kiran Muppala  <cmuppala@apple.com>
    213
  • trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt

    r122741 r125817  
    1313CONSOLE MESSAGE: Ignoring invalid Content Security Policy script nonce: 'nonces have no spaces'.
    1414
    15 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 ".
     15CONSOLE 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".
    1616
    1717None of these scripts should execute, as all the nonces are invalid.
  • trunk/Source/WebCore/ChangeLog

    r125815 r125817  
     12012-08-16  Mike West  <mkwst@chromium.org>
     2
     3        Refactor CSPDirective to support non-sourcelist types.
     4        https://bugs.webkit.org/show_bug.cgi?id=94252
     5
     6        Reviewed by Adam Barth.
     7
     8        The 'CSPDirective' was built to support source list Content Security
     9        Policy directives like 'script-src' or 'object-src'. It doesn't support
     10        new directive types like 'script-nonce' or 'plugin-types'. That
     11        functionality has been implemented by hanging state off of
     12        CSPDirectiveList, which isn't a great solution.
     13
     14        This patch pulls the source list functionality out of CSPDirective and
     15        into SourceListDirective, and likewise pulls the nonce and media list
     16        functionality into NonceDirective and MediaListDirective.
     17
     18        No new tests have been added; this refactoring should be externally
     19        transparent, and the current CSP tests should continue to pass.
     20
     21        * page/ContentSecurityPolicy.cpp:
     22        (WebCore::CSPDirective::CSPDirective):
     23        (CSPDirective):
     24        (WebCore::CSPDirective::text):
     25        (WebCore::CSPDirective::policy):
     26            CSPDirective is now a parent class for NonceDirective,
     27            MediaListDirective, and SourceListDirective. It stores a pointer
     28            to the ContentSecurityPolicy object in order to facilitate logging,
     29            which now needs to happen at this level, rather than higher up in
     30            CSPDirectiveList.
     31        (WebCore):
     32        (NonceDirective):
     33        (WebCore::NonceDirective::NonceDirective):
     34        (WebCore::NonceDirective::allows):
     35        (WebCore::NonceDirective::parse):
     36            Pull the nonce parsing code and state out of CSPDirectiveList
     37            and into this new class.
     38        (MediaListDirective):
     39        (WebCore::MediaListDirective::MediaListDirective):
     40        (WebCore::MediaListDirective::allows):
     41        (WebCore::MediaListDirective::parse):
     42            Pull the media list parsing code and state out of CSPDirectiveList
     43            and into this new class.
     44        (SourceListDirective):
     45        (WebCore::SourceListDirective::SourceListDirective):
     46        (WebCore::SourceListDirective::allows):
     47            Pull the source list functionality out of CSPDirective
     48            and into this new class.
     49        (CSPDirectiveList):
     50        (WebCore::CSPDirectiveList::checkEval):
     51        (WebCore::CSPDirectiveList::checkInline):
     52        (WebCore::CSPDirectiveList::checkNonce):
     53        (WebCore::CSPDirectiveList::checkSource):
     54        (WebCore::CSPDirectiveList::checkMediaType):
     55        (WebCore::CSPDirectiveList::operativeDirective):
     56        (WebCore::CSPDirectiveList::checkEvalAndReportViolation):
     57        (WebCore::CSPDirectiveList::checkNonceAndReportViolation):
     58        (WebCore::CSPDirectiveList::checkMediaTypeAndReportViolation):
     59        (WebCore::CSPDirectiveList::checkInlineAndReportViolation):
     60        (WebCore::CSPDirectiveList::checkSourceAndReportViolation):
     61        (WebCore::CSPDirectiveList::allowJavaScriptURLs):
     62        (WebCore::CSPDirectiveList::allowInlineEventHandlers):
     63        (WebCore::CSPDirectiveList::allowScriptNonce):
     64        (WebCore::CSPDirectiveList::allowPluginType):
     65        (WebCore::CSPDirectiveList::setCSPDirective):
     66        (WebCore::CSPDirectiveList::addDirective):
     67            Use the new classes rather than CSPDirective (or no directive
     68            at all, in the case of nonces and plugin types).
     69
    1702012-08-16  Adam Barth  <abarth@webkit.org>
    271
  • trunk/Source/WebCore/page/ContentSecurityPolicy.cpp

    r125772 r125817  
    537537public:
    538538    CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
    539         : m_sourceList(policy, name)
     539        : m_name(name)
    540540        , m_text(name + ' ' + value)
    541         , m_selfURL(policy->url())
     541        , m_policy(policy)
     542    {
     543    }
     544
     545    const String& text() const { return m_text; }
     546
     547protected:
     548    const ContentSecurityPolicy* policy() const { return m_policy; }
     549
     550private:
     551    String m_name;
     552    String m_text;
     553    ContentSecurityPolicy* m_policy;
     554};
     555
     556class NonceDirective : public CSPDirective {
     557public:
     558    NonceDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
     559        : CSPDirective(name, value, policy)
     560    {
     561        parse(value);
     562    }
     563
     564    bool allows(const String& nonce) const
     565    {
     566        return (!m_scriptNonce.isEmpty() && nonce.stripWhiteSpace() == m_scriptNonce);
     567    }
     568
     569private:
     570    void parse(const String& value)
     571    {
     572        String nonce;
     573        const UChar* position = value.characters();
     574        const UChar* end = position + value.length();
     575
     576        skipWhile<isASCIISpace>(position, end);
     577        const UChar* nonceBegin = position;
     578        if (position == end) {
     579            policy()->reportInvalidNonce(String());
     580            m_scriptNonce = "";
     581            return;
     582        }
     583        skipWhile<isNonceCharacter>(position, end);
     584        if (nonceBegin < position)
     585            nonce = String(nonceBegin, position - nonceBegin);
     586
     587        // Trim off trailing whitespace: If we're not at the end of the string, log
     588        // an error.
     589        skipWhile<isASCIISpace>(position, end);
     590        if (position < end) {
     591            policy()->reportInvalidNonce(value);
     592            m_scriptNonce = "";
     593        } else
     594            m_scriptNonce = nonce;
     595    }
     596
     597    String m_scriptNonce;
     598};
     599
     600class MediaListDirective : public CSPDirective {
     601public:
     602    MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
     603        : CSPDirective(name, value, policy)
     604    {
     605        parse(value);
     606    }
     607
     608    bool allows(const String& type)
     609    {
     610        return m_pluginTypes.contains(type);
     611    }
     612
     613private:
     614    void parse(const String& value)
     615    {
     616        const UChar* begin = value.characters();
     617        const UChar* position = begin;
     618        const UChar* end = begin + value.length();
     619
     620        // 'plugin-types ____;' OR 'plugin-types;'
     621        if (value.isEmpty()) {
     622            policy()->reportInvalidPluginTypes(value);
     623            return;
     624        }
     625
     626        while (position < end) {
     627            // _____ OR _____mime1/mime1
     628            // ^        ^
     629            skipWhile<isASCIISpace>(position, end);
     630            if (position == end)
     631                return;
     632
     633            // mime1/mime1 mime2/mime2
     634            // ^
     635            begin = position;
     636            if (!skipExactly<isMediaTypeCharacter>(position, end)) {
     637                skipWhile<isNotASCIISpace>(position, end);
     638                policy()->reportInvalidPluginTypes(String(begin, position - begin));
     639                continue;
     640            }
     641            skipWhile<isMediaTypeCharacter>(position, end);
     642
     643            // mime1/mime1 mime2/mime2
     644            //      ^
     645            if (!skipExactly(position, end, '/')) {
     646                skipWhile<isNotASCIISpace>(position, end);
     647                policy()->reportInvalidPluginTypes(String(begin, position - begin));
     648                continue;
     649            }
     650
     651            // mime1/mime1 mime2/mime2
     652            //       ^
     653            if (!skipExactly<isMediaTypeCharacter>(position, end)) {
     654                skipWhile<isNotASCIISpace>(position, end);
     655                policy()->reportInvalidPluginTypes(String(begin, position - begin));
     656                continue;
     657            }
     658            skipWhile<isMediaTypeCharacter>(position, end);
     659
     660            // mime1/mime1 mime2/mime2 OR mime1/mime1  OR mime1/mime1/error
     661            //            ^                          ^               ^
     662            if (position < end && isNotASCIISpace(*position)) {
     663                skipWhile<isNotASCIISpace>(position, end);
     664                policy()->reportInvalidPluginTypes(String(begin, position - begin));
     665                continue;
     666            }
     667            m_pluginTypes.add(String(begin, position - begin));
     668
     669            ASSERT(position == end || isASCIISpace(*position));
     670        }
     671    }
     672
     673    HashSet<String> m_pluginTypes;
     674};
     675
     676class SourceListDirective : public CSPDirective {
     677public:
     678    SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
     679        : CSPDirective(name, value, policy)
     680        , m_sourceList(policy, name)
    542681    {
    543682        m_sourceList.parse(value);
     
    546685    bool allows(const KURL& url)
    547686    {
    548         return m_sourceList.matches(url.isEmpty() ? m_selfURL : url);
     687        return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
    549688    }
    550689
     
    552691    bool allowEval() const { return m_sourceList.allowEval(); }
    553692
    554     const String& text() { return m_text; }
    555 
    556693private:
    557694    CSPSourceList m_sourceList;
    558     String m_text;
    559     KURL m_selfURL;
    560695};
    561696
     
    599734    void applySandboxPolicy(const String& name, const String& sandboxPolicy);
    600735
    601     void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirective>&);
    602 
    603     CSPDirective* operativeDirective(CSPDirective*) const;
     736    template <class CSPDirectiveType>
     737    void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>&);
     738
     739    SourceListDirective* operativeDirective(SourceListDirective*) const;
    604740    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;
    605741
    606     bool checkEval(CSPDirective*) const;
    607     bool checkInline(CSPDirective*) const;
    608     bool checkNonce(const String&) const;
    609     bool checkSource(CSPDirective*, const KURL&) const;
    610     bool checkPluginType(const String& type, const String& typeAttribute) const;
    611 
    612     bool checkEvalAndReportViolation(CSPDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack> = 0) const;
    613     bool checkInlineAndReportViolation(CSPDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
    614     bool checkNonceAndReportViolation(const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
    615     bool checkSourceAndReportViolation(CSPDirective*, const KURL&, const String& type) const;
    616     bool checkPluginTypeAndReportViolation(const String& type, const String& typeAttribute, const String& consoleMessage) const;
     742    bool checkEval(SourceListDirective*) const;
     743    bool checkInline(SourceListDirective*) const;
     744    bool checkNonce(NonceDirective*, const String&) const;
     745    bool checkSource(SourceListDirective*, const KURL&) const;
     746    bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
     747
     748    bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack> = 0) const;
     749    bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
     750    bool checkNonceAndReportViolation(NonceDirective*, const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
     751    bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& type) const;
     752    bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
    617753
    618754    bool denyIfEnforcingPolicy() const { return m_reportOnly; }
     
    624760    bool m_haveSandboxPolicy;
    625761
    626     OwnPtr<CSPDirective> m_defaultSrc;
    627     OwnPtr<CSPDirective> m_scriptSrc;
    628     OwnPtr<CSPDirective> m_objectSrc;
    629     OwnPtr<CSPDirective> m_frameSrc;
    630     OwnPtr<CSPDirective> m_imgSrc;
    631     OwnPtr<CSPDirective> m_styleSrc;
    632     OwnPtr<CSPDirective> m_fontSrc;
    633     OwnPtr<CSPDirective> m_mediaSrc;
    634     OwnPtr<CSPDirective> m_connectSrc;
    635     OwnPtr<CSPDirective> m_formAction;
     762    OwnPtr<MediaListDirective> m_pluginTypes;
     763    OwnPtr<NonceDirective> m_scriptNonce;
     764    OwnPtr<SourceListDirective> m_connectSrc;
     765    OwnPtr<SourceListDirective> m_defaultSrc;
     766    OwnPtr<SourceListDirective> m_fontSrc;
     767    OwnPtr<SourceListDirective> m_formAction;
     768    OwnPtr<SourceListDirective> m_frameSrc;
     769    OwnPtr<SourceListDirective> m_imgSrc;
     770    OwnPtr<SourceListDirective> m_mediaSrc;
     771    OwnPtr<SourceListDirective> m_objectSrc;
     772    OwnPtr<SourceListDirective> m_scriptSrc;
     773    OwnPtr<SourceListDirective> m_styleSrc;
    636774
    637775    Vector<KURL> m_reportURIs;
    638     HashSet<String> m_pluginTypes;
    639     String m_pluginTypesDirective;
    640     String m_scriptNonce;
    641776};
    642777
     
    672807}
    673808
    674 bool CSPDirectiveList::checkEval(CSPDirective* directive) const
     809bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
    675810{
    676811    return !directive || directive->allowEval();
    677812}
    678813
    679 bool CSPDirectiveList::checkInline(CSPDirective* directive) const
     814bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
    680815{
    681816    return !directive || directive->allowInline();
    682817}
    683818
    684 bool CSPDirectiveList::checkNonce(const String& nonce) const
    685 {
    686     return (m_scriptNonce.isNull()
    687             || (!m_scriptNonce.isEmpty()
    688                 && nonce.stripWhiteSpace() == m_scriptNonce));
    689 }
    690 
    691 bool CSPDirectiveList::checkSource(CSPDirective* directive, const KURL& url) const
     819bool CSPDirectiveList::checkNonce(NonceDirective* directive, const String& nonce) const
     820{
     821    return !directive || directive->allows(nonce);
     822}
     823
     824bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& url) const
    692825{
    693826    return !directive || directive->allows(url);
    694827}
    695828
    696 bool CSPDirectiveList::checkPluginType(const String& type, const String& typeAttribute) const
    697 {
    698     if (m_pluginTypesDirective.isNull())
     829bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
     830{
     831    if (!directive)
    699832        return true;
    700833    if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
    701834        return false;
    702     return m_pluginTypes.contains(type);
    703 }
    704 
    705 CSPDirective* CSPDirectiveList::operativeDirective(CSPDirective* directive) const
     835    return directive->allows(type);
     836}
     837
     838SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
    706839{
    707840    return directive ? directive : m_defaultSrc.get();
    708841}
    709842
    710 bool CSPDirectiveList::checkEvalAndReportViolation(CSPDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const
     843bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const
    711844{
    712845    if (checkEval(directive))
     
    716849}
    717850
    718 bool CSPDirectiveList::checkNonceAndReportViolation(const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
    719 {
    720     if (checkNonce(nonce))
    721         return true;
    722     reportViolation(m_scriptNonce, consoleMessage + "\"script-nonce " + m_scriptNonce + "\".\n", KURL(), contextURL, contextLine);
    723     return denyIfEnforcingPolicy();
    724 }
    725 
    726 bool CSPDirectiveList::checkPluginTypeAndReportViolation(const String& type, const String& typeAttribute, const String& consoleMessage) const
    727 {
    728     if (checkPluginType(type, typeAttribute))
    729         return true;
    730 
    731     reportViolation(m_pluginTypesDirective, consoleMessage + "'plugin-types " + m_pluginTypesDirective + "'.\n", KURL());
    732     return denyIfEnforcingPolicy();
    733 }
    734 
    735 bool CSPDirectiveList::checkInlineAndReportViolation(CSPDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
    736 {
    737     if (checkInline(directive))
     851bool CSPDirectiveList::checkNonceAndReportViolation(NonceDirective* directive, const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
     852{
     853    if (checkNonce(directive, nonce))
    738854        return true;
    739855    reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\".\n", KURL(), contextURL, contextLine);
     
    741857}
    742858
    743 bool CSPDirectiveList::checkSourceAndReportViolation(CSPDirective* directive, const KURL& url, const String& type) const
     859bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
     860{
     861    if (checkMediaType(directive, type, typeAttribute))
     862        return true;
     863
     864    reportViolation(directive->text(), consoleMessage + "\'" + directive->text() + "\'.\n", KURL());
     865    return denyIfEnforcingPolicy();
     866}
     867
     868bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
     869{
     870    if (checkInline(directive))
     871        return true;
     872    reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\".\n", KURL(), contextURL, contextLine);
     873    return denyIfEnforcingPolicy();
     874}
     875
     876bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const KURL& url, const String& type) const
    744877{
    745878    if (checkSource(directive, url))
     
    761894    if (reportingStatus == ContentSecurityPolicy::SendReport) {
    762895        return (checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine)
    763                 && checkNonceAndReportViolation(String(), consoleMessage, contextURL, contextLine));
     896                && checkNonceAndReportViolation(m_scriptNonce.get(), String(), consoleMessage, contextURL, contextLine));
    764897    } else {
    765898        return (checkInline(operativeDirective(m_scriptSrc.get()))
    766                 && checkNonce(String()));
     899                && checkNonce(m_scriptNonce.get(), String()));
    767900    }
    768901}
     
    773906    if (reportingStatus == ContentSecurityPolicy::SendReport) {
    774907        return (checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine)
    775                 && checkNonceAndReportViolation(String(), consoleMessage, contextURL, contextLine));
     908                && checkNonceAndReportViolation(m_scriptNonce.get(), String(), consoleMessage, contextURL, contextLine));
    776909    } else {
    777910        return (checkInline(operativeDirective(m_scriptSrc.get()))
    778                 && checkNonce(String()));
     911                && checkNonce(m_scriptNonce.get(), String()));
    779912    }
    780913}
     
    808941    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute script because it violates the following Content Security Policy directive: "));
    809942    if (url.isEmpty())
    810         return checkNonceAndReportViolation(nonce, consoleMessage, contextURL, contextLine);
    811     return checkNonceAndReportViolation(nonce, "Refused to load '" + url.string() + "' because it violates the following Content Security Policy directive: ", contextURL, contextLine);
     943        return checkNonceAndReportViolation(m_scriptNonce.get(), nonce, consoleMessage, contextURL, contextLine);
     944    return checkNonceAndReportViolation(m_scriptNonce.get(), nonce, "Refused to load '" + url.string() + "' because it violates the following Content Security Policy directive: ", contextURL, contextLine);
    812945}
    813946
     
    815948{
    816949    return reportingStatus == ContentSecurityPolicy::SendReport ?
    817         checkPluginTypeAndReportViolation(type, typeAttribute, "Refused to load '" + url.string() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
    818         checkPluginType(type, typeAttribute);
     950        checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.string() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
     951        checkMediaType(m_pluginTypes.get(), type, typeAttribute);
    819952}
    820953
     
    10021135}
    10031136
    1004 void CSPDirectiveList::parseScriptNonce(const String& name, const String& value)
    1005 {
    1006     if (!m_scriptNonce.isNull()) {
    1007         m_policy->reportDuplicateDirective(name);
    1008         return;
    1009     }
    1010 
    1011     String nonce;
    1012     const UChar* position = value.characters();
    1013     const UChar* end = position + value.length();
    1014 
    1015     skipWhile<isASCIISpace>(position, end);
    1016     const UChar* nonceBegin = position;
    1017     if (position == end) {
    1018         m_policy->reportInvalidNonce(String());
    1019         m_scriptNonce = "";
    1020         return;
    1021     }
    1022     skipWhile<isNonceCharacter>(position, end);
    1023     if (nonceBegin < position)
    1024         nonce = String(nonceBegin, position - nonceBegin);
    1025 
    1026     // Trim off trailing whitespace: If we're not at the end of the string, log
    1027     // an error.
    1028     skipWhile<isASCIISpace>(position, end);
    1029     if (position < end) {
    1030         m_policy->reportInvalidNonce(value);
    1031         m_scriptNonce = "";
    1032     } else
    1033         m_scriptNonce = nonce;
    1034 }
    1035 
    1036 void CSPDirectiveList::parsePluginTypes(const String& name, const String& value)
    1037 {
    1038     if (!m_pluginTypesDirective.isNull()) {
    1039         m_policy->reportDuplicateDirective(name);
    1040         return;
    1041     }
    1042 
    1043     const UChar* begin = value.characters();
    1044     const UChar* position = begin;
    1045     const UChar* end = begin + value.length();
    1046     m_pluginTypesDirective = value;
    1047 
    1048     // 'plugin-types ____;' OR 'plugin-types;'
    1049     if (value.isEmpty()) {
    1050         m_policy->reportInvalidPluginTypes(value);
    1051         m_pluginTypesDirective = "";
    1052         return;
    1053     }
    1054 
    1055     while (position < end) {
    1056         // _____ OR _____mime1/mime1
    1057         // ^        ^
    1058         skipWhile<isASCIISpace>(position, end);
    1059         if (position == end)
    1060             return;
    1061 
    1062         // mime1/mime1 mime2/mime2
    1063         // ^
    1064         begin = position;
    1065         if (!skipExactly<isMediaTypeCharacter>(position, end)) {
    1066             skipWhile<isNotASCIISpace>(position, end);
    1067             m_policy->reportInvalidPluginTypes(String(begin, position - begin));
    1068             continue;
    1069         }
    1070         skipWhile<isMediaTypeCharacter>(position, end);
    1071 
    1072         // mime1/mime1 mime2/mime2
    1073         //      ^
    1074         if (!skipExactly(position, end, '/')) {
    1075             skipWhile<isNotASCIISpace>(position, end);
    1076             m_policy->reportInvalidPluginTypes(String(begin, position - begin));
    1077             continue;
    1078         }
    1079 
    1080         // mime1/mime1 mime2/mime2
    1081         //       ^
    1082         if (!skipExactly<isMediaTypeCharacter>(position, end)) {
    1083             skipWhile<isNotASCIISpace>(position, end);
    1084             m_policy->reportInvalidPluginTypes(String(begin, position - begin));
    1085             continue;
    1086         }
    1087         skipWhile<isMediaTypeCharacter>(position, end);
    1088 
    1089         // mime1/mime1 mime2/mime2 OR mime1/mime1  OR mime1/mime1/error
    1090         //            ^                          ^               ^
    1091         if (position < end && isNotASCIISpace(*position)) {
    1092             skipWhile<isNotASCIISpace>(position, end);
    1093             m_policy->reportInvalidPluginTypes(String(begin, position - begin));
    1094             continue;
    1095         }
    1096         m_pluginTypes.add(String(begin, position - begin));
    1097 
    1098         ASSERT(position == end || isASCIISpace(*position));
    1099     }
    1100 }
    1101 
    1102 void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirective>& directive)
     1137
     1138template<class CSPDirectiveType>
     1139void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive)
    11031140{
    11041141    if (directive) {
     
    11061143        return;
    11071144    }
    1108     directive = adoptPtr(new CSPDirective(name, value, m_policy));
     1145    directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
    11091146}
    11101147
     
    11411178
    11421179    if (equalIgnoringCase(name, defaultSrc))
    1143         setCSPDirective(name, value, m_defaultSrc);
     1180        setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
    11441181    else if (equalIgnoringCase(name, scriptSrc))
    1145         setCSPDirective(name, value, m_scriptSrc);
     1182        setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
    11461183    else if (equalIgnoringCase(name, objectSrc))
    1147         setCSPDirective(name, value, m_objectSrc);
     1184        setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
    11481185    else if (equalIgnoringCase(name, frameSrc))
    1149         setCSPDirective(name, value, m_frameSrc);
     1186        setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
    11501187    else if (equalIgnoringCase(name, imgSrc))
    1151         setCSPDirective(name, value, m_imgSrc);
     1188        setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
    11521189    else if (equalIgnoringCase(name, styleSrc))
    1153         setCSPDirective(name, value, m_styleSrc);
     1190        setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
    11541191    else if (equalIgnoringCase(name, fontSrc))
    1155         setCSPDirective(name, value, m_fontSrc);
     1192        setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
    11561193    else if (equalIgnoringCase(name, mediaSrc))
    1157         setCSPDirective(name, value, m_mediaSrc);
     1194        setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
    11581195    else if (equalIgnoringCase(name, connectSrc))
    1159         setCSPDirective(name, value, m_connectSrc);
     1196        setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
    11601197    else if (equalIgnoringCase(name, sandbox))
    11611198        applySandboxPolicy(name, value);
     
    11641201#if ENABLE(CSP_NEXT)
    11651202    else if (equalIgnoringCase(name, formAction))
    1166         setCSPDirective(name, value, m_formAction);
     1203        setCSPDirective<SourceListDirective>(name, value, m_formAction);
    11671204    else if (equalIgnoringCase(name, pluginTypes))
    1168         parsePluginTypes(name, value);
     1205        setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
    11691206    else if (equalIgnoringCase(name, scriptNonce))
    1170         parseScriptNonce(name, value);
     1207        setCSPDirective<NonceDirective>(name, value, m_scriptNonce);
    11711208#endif
    11721209    else
Note: See TracChangeset for help on using the changeset viewer.