Diff
Modified: trunk/LayoutTests/ChangeLog (197943 => 197944)
--- trunk/LayoutTests/ChangeLog 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/ChangeLog 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,3 +1,26 @@
+2016-03-10 Daniel Bates <[email protected]>
+
+ CSP: Implement support for script and style nonces
+ https://bugs.webkit.org/show_bug.cgi?id=116508
+ <rdar://problem/24963980>
+
+ Reviewed by Brent Fulgham.
+
+ Update expected results due to differences between Blink and WebKit violation message formats.
+
+ Additionally mark script- and style- nonce tests as PASS in LayoutTests/TestExpectations so
+ that we run them.
+
+ * TestExpectations:
+ * http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash-expected.txt:
+ * http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash.html:
+ * http/tests/security/contentSecurityPolicy/1.1/scriptnonce-basic-blocked-expected.txt:
+ * http/tests/security/contentSecurityPolicy/1.1/scriptnonce-ignore-unsafeinline-expected.txt:
+ * http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt: Also update result
+ to reflect that we consider "'n-" an invalid source _expression_ (as expected).
+ * http/tests/security/contentSecurityPolicy/1.1/stylenonce-allowed-expected.txt:
+ * http/tests/security/contentSecurityPolicy/1.1/stylenonce-blocked-expected.txt:
+
2016-03-10 David Kilzer <[email protected]>
[iOS] DumpRenderTree crashes when accessing window.testRunner.inspectorTestStubURL
Modified: trunk/LayoutTests/TestExpectations (197943 => 197944)
--- trunk/LayoutTests/TestExpectations 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/TestExpectations 2016-03-10 18:30:38 UTC (rev 197944)
@@ -826,6 +826,13 @@
http/tests/security/contentSecurityPolicy/1.1/scripthash-malformed.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/scripthash-tests.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/scripthash-unicode-normalization.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/scriptnonce-allowed.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/scriptnonce-basic-blocked.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/scriptnonce-blocked.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/scriptnonce-ignore-unsafeinline.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/scriptnonce-redirect.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-basics.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-block-cross-origin-image-from-script.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-block-cross-origin-image.html [ Pass ]
@@ -834,6 +841,8 @@
http/tests/security/contentSecurityPolicy/1.1/securitypolicyviolation-block-image.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/stylehash-allowed.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/stylenonce-allowed.html [ Pass ]
+http/tests/security/contentSecurityPolicy/1.1/stylenonce-blocked.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/plugintypes-affects-child.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/plugintypes-invalid.html [ Pass ]
http/tests/security/contentSecurityPolicy/1.1/plugintypes-mismatched-data.html [ Pass ]
@@ -860,6 +869,8 @@
webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-error-event.html
webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/stylehash-basic-blocked-error-event.html
webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/stylehash-svg-style-basic-blocked-error-event.html
+webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/stylenonce-basic-blocked-error-event.html
+webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/stylenonce-svg-style-basic-blocked-error-event.html
webkit.org/b/153159 http/tests/security/contentSecurityPolicy/image-document-default-src-none.html [ Failure ]
webkit.org/b/153160 http/tests/security/contentSecurityPolicy/object-src-does-not-affect-child.html [ Failure ]
webkit.org/b/153160 http/tests/security/contentSecurityPolicy/plugin-in-iframe-with-csp.html [ Failure ]
Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash-expected.txt (197943 => 197944)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash-expected.txt 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash-expected.txt 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,8 +1,8 @@
ALERT: PASS (1/3)
ALERT: PASS (2/3)
ALERT: PASS (3/3)
-CONSOLE MESSAGE: line 16: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha1-MfuEFRkC2LmR31AMy9KW2ZLDegA=' 'sha1-p70t5PXyndLfjKNjbyBBOL1gFiM=' 'nonce-nonceynonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-F/kEIJZjYE56JaY4cy4cLGI8z6Rhynnwq6tihG4C9Ts='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 16: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha256-n8xN1Y8E6rPXuE8Iv++3Y3Smm6W4OGH6gqfZV7H8F1E=' 'nonce-nonceynonce'".
-CONSOLE MESSAGE: line 19: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha1-MfuEFRkC2LmR31AMy9KW2ZLDegA=' 'sha1-p70t5PXyndLfjKNjbyBBOL1gFiM=' 'nonce-nonceynonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-F26f0zRiJdDsn6iotp9pJMVvkqJpYZG+RG1eMpdaKZA='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 19: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'sha256-n8xN1Y8E6rPXuE8Iv++3Y3Smm6W4OGH6gqfZV7H8F1E=' 'nonce-nonceynonce'".
This tests the combined use of script hash and script nonce. It passes if two console warnings are visible and the three alerts show PASS.
Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash.html (197943 => 197944)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash.html 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-and-scripthash.html 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
- <meta http-equiv="Content-Security-Policy" content="script-src 'sha1-MfuEFRkC2LmR31AMy9KW2ZLDegA=' 'sha1-p70t5PXyndLfjKNjbyBBOL1gFiM=' 'nonce-nonceynonce'">
+ <meta http-equiv="Content-Security-Policy" content="script-src 'sha256-n8xN1Y8E6rPXuE8Iv++3Y3Smm6W4OGH6gqfZV7H8F1E=' 'nonce-nonceynonce'">
<script nonce="nonceynonce">
if (window.testRunner)
testRunner.dumpAsText();
Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-basic-blocked-expected.txt (197943 => 197944)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-basic-blocked-expected.txt 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-basic-blocked-expected.txt 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,9 +1,9 @@
ALERT: PASS (1/2)
ALERT: PASS (2/2)
-CONSOLE MESSAGE: line 13: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-noncynonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-1RpMm8CnZ3w3FNN+LbHHalT1URf5MlDZCUee2MAF0/U='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 13: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-noncynonce'".
-CONSOLE MESSAGE: line 16: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-noncynonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-aA5X7j5nr6U308mrny9CeIP0WyoPjaNn/0piYZqVL7I='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 16: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-noncynonce'".
-CONSOLE MESSAGE: line 19: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-noncynonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-DnnF++Kbf/s2EyTBk12Rw2Ouq//L7GY5pcHSc6IZe6U='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 19: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-noncynonce'".
This tests the effect of a valid script-nonce value. It passes if three console warnings are visible, and the two PASS alerts are executed.
Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-ignore-unsafeinline-expected.txt (197943 => 197944)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-ignore-unsafeinline-expected.txt 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-ignore-unsafeinline-expected.txt 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,5 +1,5 @@
ALERT: PASS (1/2)
ALERT: PASS (2/2)
-CONSOLE MESSAGE: line 15: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-noncynonce' 'nonce-noncy+/=nonce' 'unsafe-inline'". Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.
+CONSOLE MESSAGE: line 15: Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'nonce-noncynonce' 'nonce-noncy+/=nonce' 'unsafe-inline'".
This tests that a valid nonce disables inline _javascript_, even if 'unsafe-inline' is present.
Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt (197943 => 197944)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/scriptnonce-invalidnonce-expected.txt 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''n'. It will be ignored.
CONSOLE MESSAGE: Refused to load the script 'http://127.0.0.1:8000/security/contentSecurityPolicy/resources/script.js' because it violates the following Content Security Policy directive: "script-src 'n".
CONSOLE MESSAGE: The source list for Content Security Policy directive 'script-src' contains an invalid source: ''nonce'. It will be ignored.
Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylenonce-allowed-expected.txt (197943 => 197944)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylenonce-allowed-expected.txt 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylenonce-allowed-expected.txt 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,6 +1,6 @@
-CONSOLE MESSAGE: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'nonce-noncynonce' 'nonce-noncy+/=nonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-SKwGvORdKBYTYiM4lxIkanDyKH8J0qJ5Ix8LGkKsbhw='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 1: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'nonce-noncynonce' 'nonce-noncy+/=nonce'".
-CONSOLE MESSAGE: line 11: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'nonce-noncynonce' 'nonce-noncy+/=nonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-kv95ImKKneBhnSXrPlx5XNiVbPjFnuiudpQxG+M00io='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 11: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'nonce-noncynonce' 'nonce-noncy+/=nonce'".
Style correctly whitelisted via a 'nonce-*' _expression_ in 'style-src' should be applied to the page.
Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylenonce-blocked-expected.txt (197943 => 197944)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylenonce-blocked-expected.txt 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/1.1/stylenonce-blocked-expected.txt 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,6 +1,6 @@
-CONSOLE MESSAGE: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-SKwGvORdKBYTYiM4lxIkanDyKH8J0qJ5Ix8LGkKsbhw='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 1: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'".
-CONSOLE MESSAGE: line 6: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-cJwexfn/a5FXM2RqRmS0smWyEV/8Q3yAJM91YiT55c4='), or a nonce ('nonce-...') is required to enable inline execution.
+CONSOLE MESSAGE: line 6: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'".
Style that does not match a 'nonce-*' _expression_ in 'style-src' should not be applied to the page.
Modified: trunk/Source/WebCore/ChangeLog (197943 => 197944)
--- trunk/Source/WebCore/ChangeLog 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/ChangeLog 2016-03-10 18:30:38 UTC (rev 197944)
@@ -1,3 +1,59 @@
+2016-03-10 Daniel Bates <[email protected]>
+
+ CSP: Implement support for script and style nonces
+ https://bugs.webkit.org/show_bug.cgi?id=116508
+ <rdar://problem/24963980>
+
+ Reviewed by Brent Fulgham.
+
+ Add support for script-src and style-src nonces as per sections Nonce usage for script elements
+ and Nonce usage for style elements of the Content Security Policy 2.0 spec., <https://www.w3.org/TR/2015/CR-CSP2-20150721/>.
+
+ * dom/InlineStyleSheetOwner.cpp:
+ (WebCore::InlineStyleSheetOwner::createSheet): Check if the nonce for an HTML style element matches a known nonce.
+ * dom/ScriptElement.cpp:
+ (WebCore::ScriptElement::requestScript): Check if the nonce for an HTML script element for an external _javascript_
+ script matches a known nonce. If it does then skip subsequent checks of the Content Security Policy when loading
+ the script.
+ (WebCore::ScriptElement::executeScript): Check if the nonce for an HTML script element for an inline _javascript_
+ script matches a known nonce.
+ * html/HTMLLinkElement.cpp:
+ (WebCore::HTMLLinkElement::process): Check if the nonce for an HTML link element matches a known nonce. If it does
+ then skip subsequent checks of the Content Security Policy when loading the stylesheet.
+ * html/HTMLScriptElement.idl: Unconditionally expose attribute nonce.
+ * html/HTMLStyleElement.idl: Ditto.
+ * page/csp/ContentSecurityPolicy.cpp:
+ (WebCore::isAllowedByAllWithNonce):
+ (WebCore::ContentSecurityPolicy::allowScriptWithNonce): Check if the nonce attribute value of a script element
+ matches a known nonce. This function delegates the check to ContentSecurityPolicyDirectiveList::allowScriptWithNonce().
+ (WebCore::ContentSecurityPolicy::allowStyleWithNonce): Check if the nonce attribute value of a style/link element
+ matches a known nonce. This function delegates the check to ContentSecurityPolicyDirectiveList::allowStyleWithNonce().
+ * page/csp/ContentSecurityPolicy.h:
+ * page/csp/ContentSecurityPolicyDirectiveList.cpp:
+ (WebCore::checkNonce): Checks if the directive allows the specified nonce.
+ (WebCore::ContentSecurityPolicyDirectiveList::allowScriptWithNonce): Check if the specified nonce is in
+ the source list of the script-src directive (if specified) or the source list of the default-src directive (if specified).
+ (WebCore::ContentSecurityPolicyDirectiveList::allowStyleWithNonce): Check if the specified nonce is in
+ the source list of the style-src directive (if specified) or the source list of the default-src directive (if specified).
+ * page/csp/ContentSecurityPolicyDirectiveList.h:
+ * page/csp/ContentSecurityPolicySourceList.cpp:
+ (WebCore::ContentSecurityPolicySourceList::matches): Returns whether the specified nonce is in the HashSet of
+ nonces for the directive.
+ (WebCore::ContentSecurityPolicySourceList::parse): Modified to call ContentSecurityPolicySourceList::parseNonceSource()
+ to parse a nonce source _expression_.
+ (WebCore::isBase64Character): Moved function to be above function ContentSecurityPolicySourceList::parseNonceSource()
+ so that it can referenced from both ContentSecurityPolicySourceList::parseNonceSource() and ContentSecurityPolicySourceList::parseHashSource().
+ (WebCore::isNonceCharacter): Added. Matches Blink's definition of a valid nonce character. This definition differs
+ from the definition in the Content Security Policy Level 3 spec., <https://w3c.github.io/webappsec-csp/> (29 February 2016).
+ (WebCore::ContentSecurityPolicySourceList::parseNonceSource): Parses a source _expression_ for a nonce value.
+ * page/csp/ContentSecurityPolicySourceList.h:
+ (WebCore::ContentSecurityPolicySourceList::allowInline): We only allow inline scripts/stylesheets if
+ 'unsafe-inline' was specified in the source list and the source list does not contain any hash sources
+ or nonce sources.
+ * page/csp/ContentSecurityPolicySourceListDirective.cpp:
+ (WebCore::ContentSecurityPolicySourceListDirective::allows): Checks if the specified nonce is in the source list.
+ * page/csp/ContentSecurityPolicySourceListDirective.h:
+
2016-03-08 Sam Weinig <[email protected]>
Add a baseURL parameter to _WKUserStyleSheet
Modified: trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp (197943 => 197944)
--- trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp 2016-03-10 18:30:38 UTC (rev 197944)
@@ -135,7 +135,11 @@
if (!isValidCSSContentType(element, m_contentType))
return;
- if (!document.contentSecurityPolicy()->allowInlineStyle(document.url(), m_startTextPosition.m_line, text, element.isInUserAgentShadowTree()))
+
+ ASSERT(document.contentSecurityPolicy());
+ const ContentSecurityPolicy& contentSecurityPolicy = *document.contentSecurityPolicy();
+ bool hasKnownNonce = contentSecurityPolicy.allowStyleWithNonce(element.fastGetAttribute(HTMLNames::nonceAttr), element.isInUserAgentShadowTree());
+ if (!contentSecurityPolicy.allowInlineStyle(document.url(), m_startTextPosition.m_line, text, hasKnownNonce))
return;
RefPtr<MediaQuerySet> mediaQueries;
Modified: trunk/Source/WebCore/dom/ScriptElement.cpp (197943 => 197944)
--- trunk/Source/WebCore/dom/ScriptElement.cpp 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/dom/ScriptElement.cpp 2016-03-10 18:30:38 UTC (rev 197944)
@@ -258,8 +258,9 @@
ASSERT(!m_cachedScript);
if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
+ bool hasKnownNonce = m_element.document().contentSecurityPolicy()->allowScriptWithNonce(m_element.fastGetAttribute(HTMLNames::nonceAttr), m_element.isInUserAgentShadowTree());
ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
- options.setContentSecurityPolicyImposition(m_element.isInUserAgentShadowTree() ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck);
+ options.setContentSecurityPolicyImposition(hasKnownNonce ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck);
CachedResourceRequest request(ResourceRequest(m_element.document().completeURL(sourceUrl)), options);
@@ -293,8 +294,13 @@
if (sourceCode.isEmpty())
return;
- if (!m_isExternalScript && !m_element.document().contentSecurityPolicy()->allowInlineScript(m_element.document().url(), m_startLineNumber, sourceCode.source().toStringWithoutCopying(), m_element.isInUserAgentShadowTree()))
- return;
+ if (!m_isExternalScript) {
+ ASSERT(m_element.document().contentSecurityPolicy());
+ const ContentSecurityPolicy& contentSecurityPolicy = *m_element.document().contentSecurityPolicy();
+ bool hasKnownNonce = contentSecurityPolicy.allowScriptWithNonce(m_element.fastGetAttribute(HTMLNames::nonceAttr), m_element.isInUserAgentShadowTree());
+ if (!contentSecurityPolicy.allowInlineScript(m_element.document().url(), m_startLineNumber, sourceCode.source().toStringWithoutCopying(), hasKnownNonce))
+ return;
+ }
#if ENABLE(NOSNIFF)
if (m_isExternalScript && m_cachedScript && !m_cachedScript->mimeTypeAllowedByNosniff()) {
Modified: trunk/Source/WebCore/html/HTMLLinkElement.cpp (197943 => 197944)
--- trunk/Source/WebCore/html/HTMLLinkElement.cpp 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/html/HTMLLinkElement.cpp 2016-03-10 18:30:38 UTC (rev 197944)
@@ -32,6 +32,7 @@
#include "CachedResource.h"
#include "CachedResourceLoader.h"
#include "CachedResourceRequest.h"
+#include "ContentSecurityPolicy.h"
#include "Document.h"
#include "Event.h"
#include "EventSender.h"
@@ -245,6 +246,13 @@
priority = ResourceLoadPriority::VeryLow;
CachedResourceRequest request(ResourceRequest(document().completeURL(url)), charset, priority);
request.setInitiator(this);
+
+ if (document().contentSecurityPolicy()->allowStyleWithNonce(fastGetAttribute(HTMLNames::nonceAttr))) {
+ ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
+ options.setContentSecurityPolicyImposition(ContentSecurityPolicyImposition::SkipPolicyCheck);
+ request.setOptions(options);
+ }
+
m_cachedSheet = document().cachedResourceLoader().requestCSSStyleSheet(request);
if (m_cachedSheet)
Modified: trunk/Source/WebCore/html/HTMLScriptElement.idl (197943 => 197944)
--- trunk/Source/WebCore/html/HTMLScriptElement.idl 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/html/HTMLScriptElement.idl 2016-03-10 18:30:38 UTC (rev 197944)
@@ -29,5 +29,5 @@
[Reflect, URL] attribute DOMString src;
[Reflect] attribute DOMString type;
attribute DOMString? crossOrigin;
- [Reflect, Conditional=CSP_NEXT] attribute DOMString nonce;
+ [Reflect] attribute DOMString nonce;
};
Modified: trunk/Source/WebCore/html/HTMLStyleElement.idl (197943 => 197944)
--- trunk/Source/WebCore/html/HTMLStyleElement.idl 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/html/HTMLStyleElement.idl 2016-03-10 18:30:38 UTC (rev 197944)
@@ -25,5 +25,7 @@
// DOM Level 2 Style
readonly attribute StyleSheet sheet;
+
+ [Reflect] attribute DOMString nonce;
};
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp (197943 => 197944)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp 2016-03-10 18:30:38 UTC (rev 197944)
@@ -39,6 +39,7 @@
#include "FormData.h"
#include "FormDataList.h"
#include "Frame.h"
+#include "HTMLParserIdioms.h"
#include "InspectorInstrumentation.h"
#include "JSMainThreadExecState.h"
#include "ParsingUtilities.h"
@@ -186,6 +187,16 @@
return true;
}
+template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const String& nonce) const>
+static bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce)
+{
+ for (auto& policy : policies) {
+ if (!(policy.get()->*allowed)(nonce))
+ return false;
+ }
+ return true;
+}
+
static CryptoDigest::Algorithm toCryptoDigestAlgorithm(ContentSecurityPolicyHashAlgorithm algorithm)
{
switch (algorithm) {
@@ -252,6 +263,30 @@
return UTF8Encoding();
}
+bool ContentSecurityPolicy::allowScriptWithNonce(const String& nonce, bool overrideContentSecurityPolicy) const
+{
+ if (overrideContentSecurityPolicy)
+ return true;
+ String strippedNonce = stripLeadingAndTrailingHTMLSpaces(nonce);
+ if (strippedNonce.isEmpty())
+ return false;
+ if (isAllowedByAllWithNonce<&ContentSecurityPolicyDirectiveList::allowScriptWithNonce>(m_policies, strippedNonce))
+ return true;
+ return false;
+}
+
+bool ContentSecurityPolicy::allowStyleWithNonce(const String& nonce, bool overrideContentSecurityPolicy) const
+{
+ if (overrideContentSecurityPolicy)
+ return true;
+ String strippedNonce = stripLeadingAndTrailingHTMLSpaces(nonce);
+ if (strippedNonce.isEmpty())
+ return false;
+ if (isAllowedByAllWithNonce<&ContentSecurityPolicyDirectiveList::allowStyleWithNonce>(m_policies, strippedNonce))
+ return true;
+ return false;
+}
+
bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& scriptContent, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
{
if (overrideContentSecurityPolicy)
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h (197943 => 197944)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h 2016-03-10 18:30:38 UTC (rev 197944)
@@ -86,7 +86,9 @@
};
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 allowScriptWithNonce(const String& nonce, bool overrideContentSecurityPolicy = false) const;
bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& scriptContent, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
+ bool allowStyleWithNonce(const String& nonce, bool overrideContentSecurityPolicy = false) const;
bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& styleContent, 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;
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp (197943 => 197944)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp 2016-03-10 18:30:38 UTC (rev 197944)
@@ -125,6 +125,11 @@
return !directive || directive->allows(hash);
}
+static inline bool checkNonce(ContentSecurityPolicySourceListDirective* directive, const String& nonce)
+{
+ return !directive || directive->allows(nonce);
+}
+
static inline bool checkMediaType(ContentSecurityPolicyMediaListDirective* directive, const String& type, const String& typeAttribute)
{
if (!directive)
@@ -288,6 +293,11 @@
return checkHash(operativeDirective(m_scriptSrc.get()), hash);
}
+bool ContentSecurityPolicyDirectiveList::allowScriptWithNonce(const String& nonce) const
+{
+ return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
+}
+
bool ContentSecurityPolicyDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
{
static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to apply inline style because it violates the following Content Security Policy directive: "));
@@ -301,6 +311,11 @@
return checkHash(operativeDirective(m_styleSrc.get()), hash);
}
+bool ContentSecurityPolicyDirectiveList::allowStyleWithNonce(const String& nonce) const
+{
+ return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
+}
+
bool ContentSecurityPolicyDirectiveList::allowEval(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
{
static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to evaluate script because it violates the following Content Security Policy directive: "));
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h (197943 => 197944)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h 2016-03-10 18:30:38 UTC (rev 197944)
@@ -52,8 +52,10 @@
bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
bool allowInlineScriptWithHash(const ContentSecurityPolicyHash&) const;
+ bool allowScriptWithNonce(const String& nonce) const;
bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
bool allowInlineStyleWithHash(const ContentSecurityPolicyHash&) const;
+ bool allowStyleWithNonce(const String& nonce) const;
bool allowEval(JSC::ExecState*, ContentSecurityPolicy::ReportingStatus) const;
bool allowPluginType(const String& type, const String& typeAttribute, const URL&, ContentSecurityPolicy::ReportingStatus) const;
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp (197943 => 197944)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp 2016-03-10 18:30:38 UTC (rev 197944)
@@ -132,6 +132,11 @@
return m_hashes.contains(hash);
}
+bool ContentSecurityPolicySourceList::matches(const String& nonce) const
+{
+ return m_nonces.contains(nonce);
+}
+
// source-list = *WSP [ source *( 1*WSP source ) *WSP ]
// / *WSP "'none'" *WSP
//
@@ -152,6 +157,9 @@
bool hostHasWildcard = false;
bool portHasWildcard = false;
+ if (parseNonceSource(beginSource, position))
+ continue;
+
if (parseHashSource(beginSource, position))
continue;
@@ -395,6 +403,35 @@
return ok;
}
+static bool isBase64Character(UChar c)
+{
+ return isASCIIAlphanumeric(c) || c == '+' || c == '/' || c == '-' || c == '_';
+}
+
+// Match Blink's behavior of allowing an equal sign to appear anywhere in the value of the nonce
+// even though this does not match the behavior of Content Security Policy Level 3 spec.,
+// <https://w3c.github.io/webappsec-csp/> (29 February 2016).
+static bool isNonceCharacter(UChar c)
+{
+ return isBase64Character(c) || c == '=';
+}
+
+// nonce-source = "'nonce-" nonce-value "'"
+// nonce-value = base64-value
+bool ContentSecurityPolicySourceList::parseNonceSource(const UChar* begin, const UChar* end)
+{
+ static NeverDestroyed<String> noncePrefix("'nonce-", String::ConstructFromLiteral);
+ if (!StringView(begin, end - begin).startsWithIgnoringASCIICase(noncePrefix.get()))
+ return false;
+ const UChar* position = begin + noncePrefix.get().length();
+ const UChar* beginNonceValue = position;
+ skipWhile<UChar, isNonceCharacter>(position, end);
+ if (position >= end || position == beginNonceValue || *position != '\'')
+ return false;
+ m_nonces.add(String(beginNonceValue, position - beginNonceValue));
+ return true;
+}
+
static bool parseHashAlgorithmAdvancingPosition(const UChar*& position, size_t length, ContentSecurityPolicyHashAlgorithm& algorithm)
{
static struct {
@@ -418,11 +455,6 @@
return false;
}
-static bool isBase64Character(UChar c)
-{
- return isASCIIAlphanumeric(c) || c == '+' || c == '/' || c == '-' || c == '_';
-}
-
// hash-source = "'" hash-algorithm "-" base64-value "'"
// hash-algorithm = "sha256" / "sha384" / "sha512"
// base64-value = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h (197943 => 197944)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h 2016-03-10 18:30:38 UTC (rev 197944)
@@ -31,6 +31,7 @@
#include "ContentSecurityPolicySource.h"
#include <wtf/HashSet.h>
#include <wtf/OptionSet.h>
+#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -46,10 +47,11 @@
bool matches(const URL&);
bool matches(const ContentSecurityPolicyHash&) const;
+ bool matches(const String& nonce) const;
OptionSet<ContentSecurityPolicyHashAlgorithm> hashAlgorithmsUsed() const { return m_hashAlgorithmsUsed; }
- bool allowInline() const { return m_allowInline && m_hashes.isEmpty(); }
+ bool allowInline() const { return m_allowInline && m_hashes.isEmpty() && m_nonces.isEmpty(); }
bool allowEval() const { return m_allowEval; }
bool allowSelf() const { return m_allowSelf; }
@@ -62,12 +64,15 @@
bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
bool parsePath(const UChar* begin, const UChar* end, String& path);
+ bool parseNonceSource(const UChar* begin, const UChar* end);
+
bool isProtocolAllowedByStar(const URL&) const;
bool parseHashSource(const UChar* begin, const UChar* end);
const ContentSecurityPolicy& m_policy;
Vector<ContentSecurityPolicySource> m_list;
+ HashSet<String> m_nonces;
HashSet<ContentSecurityPolicyHash> m_hashes;
OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsUsed;
String m_directiveName;
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp (197943 => 197944)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp 2016-03-10 18:30:38 UTC (rev 197944)
@@ -47,6 +47,11 @@
return m_sourceList.matches(url);
}
+bool ContentSecurityPolicySourceListDirective::allows(const String& nonce) const
+{
+ return m_sourceList.matches(nonce);
+}
+
bool ContentSecurityPolicySourceListDirective::allows(const ContentSecurityPolicyHash& hash) const
{
return m_sourceList.matches(hash);
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h (197943 => 197944)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h 2016-03-10 18:24:50 UTC (rev 197943)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h 2016-03-10 18:30:38 UTC (rev 197944)
@@ -40,6 +40,7 @@
bool allows(const URL&);
bool allows(const ContentSecurityPolicyHash&) const;
+ bool allows(const String& nonce) const;
bool allowInline() const { return m_sourceList.allowInline(); }
bool allowEval() const { return m_sourceList.allowEval(); }