Diff
Modified: trunk/LayoutTests/ChangeLog (209758 => 209759)
--- trunk/LayoutTests/ChangeLog 2016-12-13 17:39:27 UTC (rev 209758)
+++ trunk/LayoutTests/ChangeLog 2016-12-13 18:21:37 UTC (rev 209759)
@@ -1,3 +1,23 @@
+2016-12-13 Daniel Bates <[email protected]>
+
+ CSP: Teach the preload scanner about the 'nonce' attribute
+ https://bugs.webkit.org/show_bug.cgi?id=161192
+ <rdar://problem/28010354>
+
+ Reviewed by Darin Adler.
+
+ Add tests to ensure that we preload <script>s and <link>s whose nonce is allowed by the
+ Content Security Policy of the page.
+
+ * http/tests/loading/do-not-preload-css-blocked-by-csp-expected.txt: Added.
+ * http/tests/loading/do-not-preload-css-blocked-by-csp.html: Added.
+ * http/tests/loading/do-not-preload-script-src-blocked-by-csp-expected.txt: Added.
+ * http/tests/loading/do-not-preload-script-src-blocked-by-csp.html: Added.
+ * http/tests/loading/preload-css-with-csp-nonce-expected.txt: Added.
+ * http/tests/loading/preload-css-with-csp-nonce.html: Added.
+ * http/tests/loading/preload-script-src-with-csp-nonce-expected.txt: Added.
+ * http/tests/loading/preload-script-src-with-csp-nonce.html: Added.
+
2016-12-13 Antti Koivisto <[email protected]>
REGRESSION (r198990): Safari - Cannot edit content inside <details> in wysiwyg editor
Added: trunk/LayoutTests/http/tests/loading/do-not-preload-css-blocked-by-csp-expected.txt (0 => 209759)
--- trunk/LayoutTests/http/tests/loading/do-not-preload-css-blocked-by-csp-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/loading/do-not-preload-css-blocked-by-csp-expected.txt 2016-12-13 18:21:37 UTC (rev 209759)
@@ -0,0 +1,9 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/loading/resources/small_mq.css because it does not appear in the style-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/loading/resources/small_mq.css because it does not appear in the style-src directive of the Content Security Policy.
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+This test makes sure that the Preload scanner does not preload a stylesheet resource that is blocked by the Content Security Policy of the page.
+PASS
Added: trunk/LayoutTests/http/tests/loading/do-not-preload-css-blocked-by-csp.html (0 => 209759)
--- trunk/LayoutTests/http/tests/loading/do-not-preload-css-blocked-by-csp.html (rev 0)
+++ trunk/LayoutTests/http/tests/loading/do-not-preload-css-blocked-by-csp.html 2016-12-13 18:21:37 UTC (rev 209759)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+</script>
+<meta http-equiv="Content-Security-Policy" content="script-src http://127.0.0.1:8000/resources/slow-script.pl http://127.0.0.1:8000/resources/checkPreload.js 'nonce-check-for-preload'; style-src 'none'">
+<script src=""
+<script src=""
+<link rel="stylesheet" href="" nonce="dummy">
+</head>
+<body>
+This test makes sure that the Preload scanner does not preload a stylesheet resource that is blocked by the Content Security Policy of the page.
+<br>
+<script nonce="check-for-preload">
+checkForPreload("resources/small_mq.css", false);
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/loading/do-not-preload-script-src-blocked-by-csp-expected.txt (0 => 209759)
--- trunk/LayoutTests/http/tests/loading/do-not-preload-script-src-blocked-by-csp-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/loading/do-not-preload-script-src-blocked-by-csp-expected.txt 2016-12-13 18:21:37 UTC (rev 209759)
@@ -0,0 +1,9 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/loading/resources/zero-length.js because it does not appear in the script-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/loading/resources/zero-length.js because it does not appear in the script-src directive of the Content Security Policy.
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+This test makes sure that the Preload scanner does not preload a script resource that is blocked by the Content Security Policy of the page.
+PASS
Added: trunk/LayoutTests/http/tests/loading/do-not-preload-script-src-blocked-by-csp.html (0 => 209759)
--- trunk/LayoutTests/http/tests/loading/do-not-preload-script-src-blocked-by-csp.html (rev 0)
+++ trunk/LayoutTests/http/tests/loading/do-not-preload-script-src-blocked-by-csp.html 2016-12-13 18:21:37 UTC (rev 209759)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+</script>
+<meta http-equiv="Content-Security-Policy" content="script-src http://127.0.0.1:8000/resources/slow-script.pl http://127.0.0.1:8000/resources/checkPreload.js 'nonce-check-for-preload'">
+<script src=""
+<script src=""
+</head>
+<body>
+This test makes sure that the Preload scanner does not preload a script resource that is blocked by the Content Security Policy of the page.
+<br>
+<script nonce="check-for-preload">
+checkForPreload("resources/zero-length.js", false);
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/loading/preload-css-with-csp-nonce-expected.txt (0 => 209759)
--- trunk/LayoutTests/http/tests/loading/preload-css-with-csp-nonce-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/loading/preload-css-with-csp-nonce-expected.txt 2016-12-13 18:21:37 UTC (rev 209759)
@@ -0,0 +1,7 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+This test makes sure that the Preload scanner preloads a stylesheet resource with a nonce attribute.
+PASS
Added: trunk/LayoutTests/http/tests/loading/preload-css-with-csp-nonce.html (0 => 209759)
--- trunk/LayoutTests/http/tests/loading/preload-css-with-csp-nonce.html (rev 0)
+++ trunk/LayoutTests/http/tests/loading/preload-css-with-csp-nonce.html 2016-12-13 18:21:37 UTC (rev 209759)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+</script>
+<meta http-equiv="Content-Security-Policy" content="script-src http://127.0.0.1:8000/resources/slow-script.pl http://127.0.0.1:8000/resources/checkPreload.js 'nonce-check-for-preload'; style-src 'nonce-dummy'">
+<script src=""
+<script src=""
+<link rel="stylesheet" href="" nonce="dummy">
+</head>
+<body>
+This test makes sure that the Preload scanner preloads a stylesheet resource with a nonce attribute.
+<br>
+<script nonce="check-for-preload">
+checkForPreload("resources/small_mq.css", true);
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/loading/preload-script-src-with-csp-nonce-expected.txt (0 => 209759)
--- trunk/LayoutTests/http/tests/loading/preload-script-src-with-csp-nonce-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/loading/preload-script-src-with-csp-nonce-expected.txt 2016-12-13 18:21:37 UTC (rev 209759)
@@ -0,0 +1,7 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+This test makes sure that the Preload scanner preloads a script resource with a nonce attribute.
+PASS
Added: trunk/LayoutTests/http/tests/loading/preload-script-src-with-csp-nonce.html (0 => 209759)
--- trunk/LayoutTests/http/tests/loading/preload-script-src-with-csp-nonce.html (rev 0)
+++ trunk/LayoutTests/http/tests/loading/preload-script-src-with-csp-nonce.html 2016-12-13 18:21:37 UTC (rev 209759)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+</script>
+<meta http-equiv="Content-Security-Policy" content="script-src http://127.0.0.1:8000/resources/slow-script.pl http://127.0.0.1:8000/resources/checkPreload.js 'nonce-check-for-preload' 'nonce-dummy'">
+<script src=""
+<script src=""
+</head>
+<body>
+This test makes sure that the Preload scanner preloads a script resource with a nonce attribute.
+<br>
+<script nonce="check-for-preload">
+checkForPreload("resources/zero-length.js", true);
+</script>
+<script src="" nonce="dummy"></script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (209758 => 209759)
--- trunk/Source/WebCore/ChangeLog 2016-12-13 17:39:27 UTC (rev 209758)
+++ trunk/Source/WebCore/ChangeLog 2016-12-13 18:21:37 UTC (rev 209759)
@@ -1,3 +1,40 @@
+2016-12-13 Daniel Bates <[email protected]>
+
+ CSP: Teach the preload scanner about the 'nonce' attribute
+ https://bugs.webkit.org/show_bug.cgi?id=161192
+ <rdar://problem/28010354>
+
+ Reviewed by Darin Adler.
+
+ This patch was inspired by a similar Blink change:
+ <https://chromium.googlesource.com/chromium/src/+/dde5487f380cf774e4c0e96ba7f88ea68e723907>
+
+ Preload external scripts and stylesheets whose HTML script and link elements have a nonce
+ attribute that is listed in the Content Security Policy (CSP) of the page.
+
+ Currently the preload scanner ignores the nonce attribute on HTML script and link elements.
+ So, WebKit does not preload their associated subresources unless the value of the src
+ attribute or href attribute is whitelisted in the CSP of the page for script and link
+ elements, respectively. Instead the preload scanner should recognize the nonce attribute on
+ script and link elements and query the CSP of the page with it. If the nonce attribute is
+ whitelisted then the request should be preloaded.
+
+ Tests: http/tests/loading/do-not-preload-css-blocked-by-csp.html
+ http/tests/loading/do-not-preload-script-src-blocked-by-csp.html
+ http/tests/loading/preload-css-with-csp-nonce.html
+ http/tests/loading/preload-script-src-with-csp-nonce.html
+
+ * html/parser/HTMLPreloadScanner.cpp:
+ (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): Set the nonce on the
+ PreloadRequest to the nonce that we found during the scan.
+ (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): For script and link tag names,
+ save the value of the nonce attribute (if it has one).
+ * html/parser/HTMLResourcePreloader.cpp:
+ (WebCore::PreloadRequest::resourceRequest): Skip CSP policy check if the nonce is listed in
+ the CSP of the page.
+ * html/parser/HTMLResourcePreloader.h:
+ (WebCore::PreloadRequest::setNonce): Added.
+
2016-12-13 Dave Hyatt <[email protected]>
[CSS Parser] Rename CSSPrimitiveValue::UnitTypes to CSSPrimitiveValue::UnitType
Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp (209758 => 209759)
--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp 2016-12-13 17:39:27 UTC (rev 209758)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp 2016-12-13 18:21:37 UTC (rev 209759)
@@ -147,6 +147,7 @@
auto request = std::make_unique<PreloadRequest>(initiatorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute, m_moduleScript);
request->setCrossOriginMode(m_crossOriginMode);
+ request->setNonce(m_nonceAttribute);
// According to the spec, the module tag ignores the "charset" attribute as the same to the worker's
// importScript. But WebKit supports the "charset" for importScript intentionally. So to be consistent,
@@ -216,7 +217,8 @@
m_moduleScript = equalLettersIgnoringASCIICase(attributeValue, "module") ? PreloadRequest::ModuleScript::Yes : PreloadRequest::ModuleScript::No;
break;
}
- }
+ } else if (match(attributeName, nonceAttr))
+ m_nonceAttribute = attributeValue;
processImageAndScriptAttribute(attributeName, attributeValue);
break;
case TagId::Link:
@@ -230,6 +232,8 @@
m_charset = attributeValue;
else if (match(attributeName, crossoriginAttr))
m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeValue);
+ else if (match(attributeName, nonceAttr))
+ m_nonceAttribute = attributeValue;
break;
case TagId::Input:
if (match(attributeName, srcAttr))
@@ -326,6 +330,7 @@
String m_crossOriginMode;
bool m_linkIsStyleSheet;
String m_mediaAttribute;
+ String m_nonceAttribute;
String m_metaContent;
bool m_metaIsViewport;
bool m_inputIsImage;
Modified: trunk/Source/WebCore/html/parser/HTMLResourcePreloader.cpp (209758 => 209759)
--- trunk/Source/WebCore/html/parser/HTMLResourcePreloader.cpp 2016-12-13 17:39:27 UTC (rev 209758)
+++ trunk/Source/WebCore/html/parser/HTMLResourcePreloader.cpp 2016-12-13 18:21:37 UTC (rev 209759)
@@ -43,7 +43,18 @@
CachedResourceRequest PreloadRequest::resourceRequest(Document& document)
{
ASSERT(isMainThread());
- CachedResourceRequest request(completeURL(document), CachedResourceLoader::defaultCachedResourceOptions());
+
+ bool skipContentSecurityPolicyCheck = false;
+ if (m_resourceType == CachedResource::Type::Script)
+ skipContentSecurityPolicyCheck = document.contentSecurityPolicy()->allowScriptWithNonce(m_nonceAttribute);
+ else if (m_resourceType == CachedResource::Type::CSSStyleSheet)
+ skipContentSecurityPolicyCheck = document.contentSecurityPolicy()->allowStyleWithNonce(m_nonceAttribute);
+
+ ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
+ if (skipContentSecurityPolicyCheck)
+ options.contentSecurityPolicyImposition = ContentSecurityPolicyImposition::SkipPolicyCheck;
+
+ CachedResourceRequest request { completeURL(document), options };
request.setInitiator(m_initiator);
String crossOriginMode = m_crossOriginMode;
if (m_moduleScript == ModuleScript::Yes) {
Modified: trunk/Source/WebCore/html/parser/HTMLResourcePreloader.h (209758 => 209759)
--- trunk/Source/WebCore/html/parser/HTMLResourcePreloader.h 2016-12-13 17:39:27 UTC (rev 209758)
+++ trunk/Source/WebCore/html/parser/HTMLResourcePreloader.h 2016-12-13 18:21:37 UTC (rev 209759)
@@ -53,6 +53,7 @@
const String& media() const { return m_mediaAttribute; }
void setCharset(const String& charset) { m_charset = charset.isolatedCopy(); }
void setCrossOriginMode(const String& mode) { m_crossOriginMode = mode; }
+ void setNonce(const String& nonce) { m_nonceAttribute = nonce; }
CachedResource::Type resourceType() const { return m_resourceType; }
private:
@@ -65,6 +66,7 @@
CachedResource::Type m_resourceType;
String m_mediaAttribute;
String m_crossOriginMode;
+ String m_nonceAttribute;
ModuleScript m_moduleScript;
};