From 516aa049f57091e02b14420771e498babc40c2df Mon Sep 17 00:00:00 2001 From: "abarth@webkit.org" Date: Thu, 7 Apr 2011 20:51:22 +0000 Subject: [PATCH] 2011-04-07 Adam Barth Reviewed by Eric Seidel. Implement CSP's options directive https://bugs.webkit.org/show_bug.cgi?id=58014 * http/tests/security/contentSecurityPolicy/inline-script-allowed-expected.txt: Added. * http/tests/security/contentSecurityPolicy/inline-script-allowed.html: Added. * http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy-expected.txt: Added. * http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy.html: Added. 2011-04-07 Adam Barth Reviewed by Eric Seidel. Implement CSP's options directive https://bugs.webkit.org/show_bug.cgi?id=58014 This patch contains the full options parser, but we only have enough of CSP implemented to see the effects of disable-xss-protection. Will need to do some more work before we can see eval-script in action. Tests: http/tests/security/contentSecurityPolicy/inline-script-allowed.html http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy.html * page/ContentSecurityPolicy.cpp: (WebCore::CSPOptions::CSPOptions): (WebCore::CSPOptions::disableXSSProtection): (WebCore::CSPOptions::evalScript): (WebCore::CSPOptions::parse): (WebCore::ContentSecurityPolicy::allowJavaScriptURLs): (WebCore::ContentSecurityPolicy::allowInlineEventHandlers): (WebCore::ContentSecurityPolicy::allowInlineScript): (WebCore::ContentSecurityPolicy::addDirective): * page/ContentSecurityPolicy.h: git-svn-id: https://svn.webkit.org/repository/webkit/trunk@83205 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 12 ++++ .../inline-script-allowed-expected.txt | 4 ++ .../inline-script-allowed.html | 13 +++++ .../inline-script-blocked-goofy-expected.txt | 1 + .../inline-script-blocked-goofy.html | 14 +++++ Source/WebCore/ChangeLog | 25 ++++++++ Source/WebCore/page/ContentSecurityPolicy.cpp | 68 +++++++++++++++++++++- Source/WebCore/page/ContentSecurityPolicy.h | 4 ++ 8 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-allowed-expected.txt create mode 100644 LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-allowed.html create mode 100644 LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy-expected.txt create mode 100644 LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy.html diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 1b52658..30e7de0 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,15 @@ +2011-04-07 Adam Barth + + Reviewed by Eric Seidel. + + Implement CSP's options directive + https://bugs.webkit.org/show_bug.cgi?id=58014 + + * http/tests/security/contentSecurityPolicy/inline-script-allowed-expected.txt: Added. + * http/tests/security/contentSecurityPolicy/inline-script-allowed.html: Added. + * http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy-expected.txt: Added. + * http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy.html: Added. + 2011-04-07 Enrica Casucci Unreviewed. diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-allowed-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-allowed-expected.txt new file mode 100644 index 0000000..276099c --- /dev/null +++ b/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-allowed-expected.txt @@ -0,0 +1,4 @@ +ALERT: PASS 1 of 3 +ALERT: PASS 2 of 3 +ALERT: PASS 3 of 3 + diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-allowed.html b/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-allowed.html new file mode 100644 index 0000000..b07431e --- /dev/null +++ b/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-allowed.html @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy-expected.txt new file mode 100644 index 0000000..d04a3fb --- /dev/null +++ b/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy-expected.txt @@ -0,0 +1 @@ +This test passes if it doesn't alert fail. diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy.html b/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy.html new file mode 100644 index 0000000..a67d56f --- /dev/null +++ b/LayoutTests/http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy.html @@ -0,0 +1,14 @@ + + + + + + + +This test passes if it doesn't alert fail. + + + + diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index fad5a3c..15e3284 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,28 @@ +2011-04-07 Adam Barth + + Reviewed by Eric Seidel. + + Implement CSP's options directive + https://bugs.webkit.org/show_bug.cgi?id=58014 + + This patch contains the full options parser, but we only have enough of + CSP implemented to see the effects of disable-xss-protection. Will + need to do some more work before we can see eval-script in action. + + Tests: http/tests/security/contentSecurityPolicy/inline-script-allowed.html + http/tests/security/contentSecurityPolicy/inline-script-blocked-goofy.html + + * page/ContentSecurityPolicy.cpp: + (WebCore::CSPOptions::CSPOptions): + (WebCore::CSPOptions::disableXSSProtection): + (WebCore::CSPOptions::evalScript): + (WebCore::CSPOptions::parse): + (WebCore::ContentSecurityPolicy::allowJavaScriptURLs): + (WebCore::ContentSecurityPolicy::allowInlineEventHandlers): + (WebCore::ContentSecurityPolicy::allowInlineScript): + (WebCore::ContentSecurityPolicy::addDirective): + * page/ContentSecurityPolicy.h: + 2011-04-07 Alexey Proskuryakov Reviewed by Anders Carlsson. diff --git a/Source/WebCore/page/ContentSecurityPolicy.cpp b/Source/WebCore/page/ContentSecurityPolicy.cpp index b8989af..a92b428 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.cpp +++ b/Source/WebCore/page/ContentSecurityPolicy.cpp @@ -57,6 +57,11 @@ bool isHostCharacter(UChar c) return isASCIIAlphanumeric(c) || c == '-'; } +bool isOptionValueCharacter(UChar c) +{ + return isASCIIAlphanumeric(c) || c == '-'; +} + bool isSchemeContinuationCharacter(UChar c) { return isASCIIAlphanumeric(c) || c == '+' || c == '-' || c == '.'; @@ -406,6 +411,55 @@ private: CSPSourceList m_sourceList; }; +class CSPOptions { +public: + explicit CSPOptions(const String& value) + : m_disableXSSProtection(false) + , m_evalScript(false) + { + parse(value); + } + + bool disableXSSProtection() const { return m_disableXSSProtection; } + bool evalScript() const { return m_evalScript; } + +private: + void parse(const String&); + + bool m_disableXSSProtection; + bool m_evalScript; +}; + +// options = "options" *( 1*WSP option-value ) *WSP +// option-value = 1*( ALPHA / DIGIT / "-" ) +// +void CSPOptions::parse(const String& value) +{ + DEFINE_STATIC_LOCAL(String, disableXSSProtection, ("disable-xss-protection")); + DEFINE_STATIC_LOCAL(String, evalScript, ("eval-script")); + + const UChar* position = value.characters(); + const UChar* end = position + value.length(); + + while (position < end) { + skipWhile(position, end); + + const UChar* optionsValueBegin = position; + + if (!skipExactly(position, end)) + return; + + skipWhile(position, end); + + String optionsValue(optionsValueBegin, position - optionsValueBegin); + + if (equalIgnoringCase(optionsValue, disableXSSProtection)) + m_disableXSSProtection = true; + else if (equalIgnoringCase(optionsValue, evalScript)) + m_evalScript = true; + } +} + ContentSecurityPolicy::ContentSecurityPolicy(SecurityOrigin* origin) : m_havePolicy(false) , m_origin(origin) @@ -425,19 +479,24 @@ void ContentSecurityPolicy::didReceiveHeader(const String& header) m_havePolicy = true; } +bool ContentSecurityPolicy::protectAgainstXSS() const +{ + return m_scriptSrc && (!m_options || !m_options->disableXSSProtection()); +} + bool ContentSecurityPolicy::allowJavaScriptURLs() const { - return !m_scriptSrc; + return !protectAgainstXSS(); } bool ContentSecurityPolicy::allowInlineEventHandlers() const { - return !m_scriptSrc; + return !protectAgainstXSS(); } bool ContentSecurityPolicy::allowInlineScript() const { - return !m_scriptSrc; + return !protectAgainstXSS(); } bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url) const @@ -525,6 +584,7 @@ void ContentSecurityPolicy::addDirective(const String& name, const String& value { DEFINE_STATIC_LOCAL(String, scriptSrc, ("script-src")); DEFINE_STATIC_LOCAL(String, objectSrc, ("object-src")); + DEFINE_STATIC_LOCAL(String, options, ("options")); ASSERT(!name.isEmpty()); @@ -532,6 +592,8 @@ void ContentSecurityPolicy::addDirective(const String& name, const String& value m_scriptSrc = adoptPtr(new CSPDirective(value, m_origin.get())); else if (!m_objectSrc && equalIgnoringCase(name, objectSrc)) m_objectSrc = adoptPtr(new CSPDirective(value, m_origin.get())); + else if (!m_options && equalIgnoringCase(name, options)) + m_options = adoptPtr(new CSPOptions(value)); } } diff --git a/Source/WebCore/page/ContentSecurityPolicy.h b/Source/WebCore/page/ContentSecurityPolicy.h index 750a443..7ec4ffc 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.h +++ b/Source/WebCore/page/ContentSecurityPolicy.h @@ -32,6 +32,7 @@ namespace WebCore { class CSPDirective; +class CSPOptions; class KURL; class SecurityOrigin; @@ -54,6 +55,8 @@ public: private: explicit ContentSecurityPolicy(SecurityOrigin*); + bool protectAgainstXSS() const; + void parse(const String&); bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value); void addDirective(const String& name, const String& value); @@ -62,6 +65,7 @@ private: RefPtr m_origin; OwnPtr m_scriptSrc; OwnPtr m_objectSrc; + OwnPtr m_options; }; } -- 1.8.3.1