<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[206716] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/206716">206716</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-10-02 06:59:18 -0700 (Sun, 02 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Fetch API] Forbid redirection to non-HTTP(s) URL in non-navigation mode.
https://bugs.webkit.org/show_bug.cgi?id=162785

Patch by Youenn Fablet &lt;youenn@apple.com&gt; on 2016-10-02
Reviewed by Alex Christensen.

LayoutTests/imported/w3c:

* web-platform-tests/fetch/api/redirect/redirect-to-dataurl-expected.txt:
* web-platform-tests/fetch/api/redirect/redirect-to-dataurl-worker-expected.txt:

Source/WebCore:

Covered by rebased and existing tests.

Ensuring non-HTTP redirection URLs are not followed at DocumentThreadableLoader level for fetch API only.
This should be applied to all clients at some point, but there is still some uncertainty for data URLs.

Did some refactoring to better separate the case of security checks in case of regular request or redirected request.
This allows in particular to handle more clearly the case of data URLs which are allowed in all modes for regular requests.
But they are not allowed for same-origin redirected requests.

* WebCore.xcodeproj/project.pbxproj:
* loader/DocumentThreadableLoader.cpp:
(WebCore::reportRedirectionWithBadScheme): Reporting bad scheme redirection error.
(WebCore::DocumentThreadableLoader::redirectReceived): Checking that redirection URLs are HTTP(s) in case of Fetch API.
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::willSendRequestInternal):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::requestImage):
(WebCore::CachedResourceLoader::checkInsecureContent):
(WebCore::CachedResourceLoader::allowedByContentSecurityPolicy):
(WebCore::isSameOriginDataURL):
(WebCore::CachedResourceLoader::canRequest):
(WebCore::CachedResourceLoader::canRequestAfterRedirection):
(WebCore::CachedResourceLoader::canRequestInContentDispositionAttachmentSandbox):
(WebCore::CachedResourceLoader::requestResource):
* loader/cache/CachedResourceLoader.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapiredirectredirecttodataurlexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapiredirectredirecttodataurlworkerexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl-worker-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreloaderDocumentThreadableLoadercpp">trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderSubresourceLoadercpp">trunk/Source/WebCore/loader/SubresourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceLoadercpp">trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceLoaderh">trunk/Source/WebCore/loader/cache/CachedResourceLoader.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/LayoutTests/imported/w3c/ChangeLog        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-10-02  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        [Fetch API] Forbid redirection to non-HTTP(s) URL in non-navigation mode.
+        https://bugs.webkit.org/show_bug.cgi?id=162785
+
+        Reviewed by Alex Christensen.
+
+        * web-platform-tests/fetch/api/redirect/redirect-to-dataurl-expected.txt:
+        * web-platform-tests/fetch/api/redirect/redirect-to-dataurl-worker-expected.txt:
+
</ins><span class="cx"> 2016-09-30  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fragment serialization should always use 'xml:' prefix for attributes in XML namespace
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapiredirectredirecttodataurlexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl-expected.txt (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl-expected.txt        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl-expected.txt        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -4,8 +4,8 @@
</span><span class="cx"> CONSOLE MESSAGE: Cross-origin redirection to data:text/plain;base64,cmVzcG9uc2UncyBib2R5 denied by Cross-Origin Resource Sharing policy: URL is either a non-HTTP URL or contains credentials.
</span><span class="cx"> 
</span><span class="cx"> PASS Testing data URL loading after same-origin redirection (cors mode) 
</span><del>-FAIL Testing data URL loading after same-origin redirection (no-cors mode) assert_unreached: Should have rejected. Reached unreachable code
</del><ins>+PASS Testing data URL loading after same-origin redirection (no-cors mode) 
</ins><span class="cx"> PASS Testing data URL loading after same-origin redirection (same-origin mode) 
</span><span class="cx"> PASS Testing data URL loading after cross-origin redirection (cors mode) 
</span><del>-FAIL Testing data URL loading after cross-origin redirection (no-cors mode) assert_unreached: Should have rejected. Reached unreachable code
</del><ins>+PASS Testing data URL loading after cross-origin redirection (no-cors mode) 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapiredirectredirecttodataurlworkerexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl-worker-expected.txt (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl-worker-expected.txt        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-to-dataurl-worker-expected.txt        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -4,8 +4,8 @@
</span><span class="cx"> CONSOLE MESSAGE: Cross-origin redirection to data:text/plain;base64,cmVzcG9uc2UncyBib2R5 denied by Cross-Origin Resource Sharing policy: URL is either a non-HTTP URL or contains credentials.
</span><span class="cx"> 
</span><span class="cx"> PASS Testing data URL loading after same-origin redirection (cors mode) 
</span><del>-FAIL Testing data URL loading after same-origin redirection (no-cors mode) assert_unreached: Should have rejected. Reached unreachable code
</del><ins>+PASS Testing data URL loading after same-origin redirection (no-cors mode) 
</ins><span class="cx"> PASS Testing data URL loading after same-origin redirection (same-origin mode) 
</span><span class="cx"> PASS Testing data URL loading after cross-origin redirection (cors mode) 
</span><del>-FAIL Testing data URL loading after cross-origin redirection (no-cors mode) assert_unreached: Should have rejected. Reached unreachable code
</del><ins>+PASS Testing data URL loading after cross-origin redirection (no-cors mode) 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/Source/WebCore/ChangeLog        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2016-10-02  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        [Fetch API] Forbid redirection to non-HTTP(s) URL in non-navigation mode.
+        https://bugs.webkit.org/show_bug.cgi?id=162785
+
+        Reviewed by Alex Christensen.
+
+        Covered by rebased and existing tests.
+
+        Ensuring non-HTTP redirection URLs are not followed at DocumentThreadableLoader level for fetch API only.
+        This should be applied to all clients at some point, but there is still some uncertainty for data URLs.
+
+        Did some refactoring to better separate the case of security checks in case of regular request or redirected request.
+        This allows in particular to handle more clearly the case of data URLs which are allowed in all modes for regular requests.
+        But they are not allowed for same-origin redirected requests.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::reportRedirectionWithBadScheme): Reporting bad scheme redirection error.
+        (WebCore::DocumentThreadableLoader::redirectReceived): Checking that redirection URLs are HTTP(s) in case of Fetch API.
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::willSendRequestInternal):
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::CachedResourceLoader::requestImage):
+        (WebCore::CachedResourceLoader::checkInsecureContent):
+        (WebCore::CachedResourceLoader::allowedByContentSecurityPolicy):
+        (WebCore::isSameOriginDataURL):
+        (WebCore::CachedResourceLoader::canRequest):
+        (WebCore::CachedResourceLoader::canRequestAfterRedirection):
+        (WebCore::CachedResourceLoader::canRequestInContentDispositionAttachmentSandbox):
+        (WebCore::CachedResourceLoader::requestResource):
+        * loader/cache/CachedResourceLoader.h:
+
</ins><span class="cx"> 2016-10-01  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Support transitions/animations of background-position with right/bottom-relative values
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -5791,7 +5791,7 @@
</span><span class="cx">                 CE2849871CA360DF00B4A57F /* ContentSecurityPolicyDirectiveNames.h in Headers */ = {isa = PBXBuildFile; fileRef = CE2849861CA360DF00B4A57F /* ContentSecurityPolicyDirectiveNames.h */; };
</span><span class="cx">                 CE2849891CA3614600B4A57F /* ContentSecurityPolicyDirectiveNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE2849881CA3614600B4A57F /* ContentSecurityPolicyDirectiveNames.cpp */; };
</span><span class="cx">                 CE6DADF91C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE6DADF71C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp */; };
</span><del>-                CE6DADFA1C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = CE6DADF81C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h */; };
</del><ins>+                CE6DADFA1C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = CE6DADF81C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 CE799F971C6A46BC0097B518 /* ContentSecurityPolicySourceList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE799F951C6A46BC0097B518 /* ContentSecurityPolicySourceList.cpp */; };
</span><span class="cx">                 CE799F981C6A46BC0097B518 /* ContentSecurityPolicySourceList.h in Headers */ = {isa = PBXBuildFile; fileRef = CE799F961C6A46BC0097B518 /* ContentSecurityPolicySourceList.h */; };
</span><span class="cx">                 CE799F9B1C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE799F991C6A4BCD0097B518 /* ContentSecurityPolicyDirectiveList.cpp */; };
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderDocumentThreadableLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -216,6 +216,11 @@
</span><span class="cx">     client.didFail(ResourceError(errorDomainWebKitInternal, 0, url, &quot;Cross-origin redirection denied by Cross-Origin Resource Sharing policy.&quot;, ResourceError::Type::AccessControl));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline void reportRedirectionWithBadScheme(ThreadableLoaderClient&amp; client, const URL&amp; url)
+{
+    client.didFail(ResourceError(errorDomainWebKitInternal, 0, url, &quot;Redirection to URL with a scheme that is not HTTP(S).&quot;, ResourceError::Type::AccessControl));
+}
+
</ins><span class="cx"> void DocumentThreadableLoader::redirectReceived(CachedResource* resource, ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_client);
</span><span class="lines">@@ -222,6 +227,16 @@
</span><span class="cx">     ASSERT_UNUSED(resource, resource == m_resource);
</span><span class="cx"> 
</span><span class="cx">     Ref&lt;DocumentThreadableLoader&gt; protectedThis(*this);
</span><ins>+
+    // FIXME: We restrict this check to Fetch API for the moment, as this might disrupt WorkerScriptLoader.
+    // Reassess this check based on https://github.com/whatwg/fetch/issues/393 discussions.
+    // We should also disable that check in navigation mode.
+    if (!request.url().protocolIsInHTTPFamily() &amp;&amp; m_options.initiator == cachedResourceRequestInitiators().fetch) {
+        reportRedirectionWithBadScheme(*m_client, request.url());
+        clearResource();
+        return;
+    }
+
</ins><span class="cx">     if (!isAllowedByContentSecurityPolicy(request.url(), redirectResponse.isNull() ? ContentSecurityPolicy::RedirectResponseReceived::No : ContentSecurityPolicy::RedirectResponseReceived::Yes)) {
</span><span class="cx">         reportContentSecurityPolicyError(*m_client, redirectResponse.url());
</span><span class="cx">         clearResource();
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderSubresourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/SubresourceLoader.cpp        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -200,7 +200,7 @@
</span><span class="cx">                 m_frame-&gt;page()-&gt;diagnosticLoggingClient().logDiagnosticMessageWithResult(DiagnosticLoggingKeys::cachedResourceRevalidationKey(), emptyString(), DiagnosticLoggingResultFail, ShouldSample::Yes);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (!m_documentLoader-&gt;cachedResourceLoader().canRequest(m_resource-&gt;type(), newRequest.url(), options(), false /* forPreload */, true /* didReceiveRedirectResponse */)) {
</del><ins>+        if (!m_documentLoader-&gt;cachedResourceLoader().canRequestAfterRedirection(m_resource-&gt;type(), newRequest.url(), options())) {
</ins><span class="cx">             cancel();
</span><span class="cx">             return;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -183,7 +183,7 @@
</span><span class="cx">             if (Document* document = frame-&gt;document())
</span><span class="cx">                 document-&gt;contentSecurityPolicy()-&gt;upgradeInsecureRequestIfNeeded(request.mutableResourceRequest(), ContentSecurityPolicy::InsecureRequestType::Load);
</span><span class="cx">             URL requestURL = request.resourceRequest().url();
</span><del>-            if (requestURL.isValid() &amp;&amp; canRequest(CachedResource::ImageResource, requestURL, request.options(), request.forPreload()))
</del><ins>+            if (requestURL.isValid() &amp;&amp; canRequest(CachedResource::ImageResource, requestURL, request))
</ins><span class="cx">                 PingLoader::loadImage(*frame, requestURL);
</span><span class="cx">             return nullptr;
</span><span class="cx">         }
</span><span class="lines">@@ -333,6 +333,10 @@
</span><span class="cx"> 
</span><span class="cx"> bool CachedResourceLoader::checkInsecureContent(CachedResource::Type type, const URL&amp; url) const
</span><span class="cx"> {
</span><ins>+
+    if (!canRequestInContentDispositionAttachmentSandbox(type, url))
+        return false;
+
</ins><span class="cx">     switch (type) {
</span><span class="cx">     case CachedResource::Script:
</span><span class="cx"> #if ENABLE(XSLT)
</span><span class="lines">@@ -379,13 +383,8 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline bool isSameOriginDataURL(const URL&amp; url, const ResourceLoaderOptions&amp; options, bool didReceiveRedirectResponse)
</del><ins>+bool CachedResourceLoader::allowedByContentSecurityPolicy(CachedResource::Type type, const URL&amp; url, const ResourceLoaderOptions&amp; options, ContentSecurityPolicy::RedirectResponseReceived redirectResponseReceived)
</ins><span class="cx"> {
</span><del>-    return !didReceiveRedirectResponse &amp;&amp; url.protocolIsData() &amp;&amp; options.sameOriginDataURLFlag == SameOriginDataURLFlag::Set;
-}
-
-bool CachedResourceLoader::allowedByContentSecurityPolicy(CachedResource::Type type, const URL&amp; url, const ResourceLoaderOptions&amp; options, bool didReceiveRedirectResponse)
-{
</del><span class="cx">     if (options.contentSecurityPolicyImposition == ContentSecurityPolicyImposition::SkipPolicyCheck)
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="lines">@@ -392,8 +391,6 @@
</span><span class="cx">     ASSERT(m_document);
</span><span class="cx">     ASSERT(m_document-&gt;contentSecurityPolicy());
</span><span class="cx"> 
</span><del>-    auto redirectResponseReceived = didReceiveRedirectResponse ? ContentSecurityPolicy::RedirectResponseReceived::Yes : ContentSecurityPolicy::RedirectResponseReceived::No;
-
</del><span class="cx">     switch (type) {
</span><span class="cx"> #if ENABLE(XSLT)
</span><span class="cx">     case CachedResource::XSLStyleSheet:
</span><span class="lines">@@ -430,25 +427,33 @@
</span><span class="cx">     default:
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><ins>+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL&amp; url, const ResourceLoaderOptions&amp; options, bool forPreload, bool didReceiveRedirectResponse)
</del><ins>+static inline bool isSameOriginDataURL(const URL&amp; url, const ResourceLoaderOptions&amp; options)
</ins><span class="cx"> {
</span><ins>+    // FIXME: Remove same-origin data URL flag since it was removed from fetch spec (https://github.com/whatwg/fetch/issues/381).
+    return url.protocolIsData() &amp;&amp; options.sameOriginDataURLFlag == SameOriginDataURLFlag::Set;
+}
+
+bool CachedResourceLoader::canRequest(CachedResource::Type type, const URL&amp; url, const CachedResourceRequest&amp; request)
+{
+    auto&amp; options = request.options();
+
</ins><span class="cx">     if (document() &amp;&amp; !document()-&gt;securityOrigin()-&gt;canDisplay(url)) {
</span><del>-        if (!forPreload)
</del><ins>+        if (!request.forPreload())
</ins><span class="cx">             FrameLoader::reportLocalLoadFailed(frame(), url.stringCenterEllipsizedToLength());
</span><span class="cx">         LOG(ResourceLoading, &quot;CachedResourceLoader::requestResource URL was not allowed by SecurityOrigin::canDisplay&quot;);
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: Remove same-origin data URL flag since it was removed from fetch spec (see https://github.com/whatwg/fetch/issues/381).
-    if (options.mode == FetchOptions::Mode::SameOrigin &amp;&amp; !isSameOriginDataURL(url, options, didReceiveRedirectResponse) &amp;&amp; !m_document-&gt;securityOrigin()-&gt;canRequest(url)) {
</del><ins>+    if (options.mode == FetchOptions::Mode::SameOrigin &amp;&amp; !m_document-&gt;securityOrigin()-&gt;canRequest(url) &amp;&amp; !isSameOriginDataURL(url, options)) {
</ins><span class="cx">         printAccessDeniedMessage(url);
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!allowedByContentSecurityPolicy(type, url, options, didReceiveRedirectResponse))
</del><ins>+    if (!allowedByContentSecurityPolicy(type, url, options, ContentSecurityPolicy::RedirectResponseReceived::No))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // SVG Images have unique security rules that prevent all subresource requests except for data urls.
</span><span class="lines">@@ -457,14 +462,38 @@
</span><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!canRequestInContentDispositionAttachmentSandbox(type, url))
</del><ins>+    // Last of all, check for insecure content. We do this last so that when folks block insecure content with a CSP policy, they don't get a warning.
+    // They'll still get a warning in the console about CSP blocking the load.
+
+    // FIXME: Should we consider whether the request is for preload here?
+    if (!checkInsecureContent(type, url))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    // Last of all, check for insecure content. We do this last so that when
-    // folks block insecure content with a CSP policy, they don't get a warning.
</del><ins>+    return true;
+}
+
+// FIXME: Should we find a way to know whether the redirection is for a preload request like we do for CachedResourceLoader::canRequest?
+bool CachedResourceLoader::canRequestAfterRedirection(CachedResource::Type type, const URL&amp; url, const ResourceLoaderOptions&amp; options)
+{
+    if (document() &amp;&amp; !document()-&gt;securityOrigin()-&gt;canDisplay(url)) {
+        FrameLoader::reportLocalLoadFailed(frame(), url.stringCenterEllipsizedToLength());
+        LOG(ResourceLoading, &quot;CachedResourceLoader::requestResource URL was not allowed by SecurityOrigin::canDisplay&quot;);
+        return false;
+    }
+
+    // FIXME: According to https://fetch.spec.whatwg.org/#http-redirect-fetch, we should check that the URL is HTTP(s) except if in navigation mode.
+    // But we currently allow at least data URLs to be loaded.
+
+    if (options.mode == FetchOptions::Mode::SameOrigin &amp;&amp; !m_document-&gt;securityOrigin()-&gt;canRequest(url)) {
+        printAccessDeniedMessage(url);
+        return false;
+    }
+
+    if (!allowedByContentSecurityPolicy(type, url, options, ContentSecurityPolicy::RedirectResponseReceived::Yes))
+        return false;
+
+    // Last of all, check for insecure content. We do this last so that when folks block insecure content with a CSP policy, they don't get a warning.
</ins><span class="cx">     // They'll still get a warning in the console about CSP blocking the load.
</span><del>-
-    // FIXME: Should we consider forPreload here?
</del><span class="cx">     if (!checkInsecureContent(type, url))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -474,7 +503,7 @@
</span><span class="cx"> bool CachedResourceLoader::canRequestInContentDispositionAttachmentSandbox(CachedResource::Type type, const URL&amp; url) const
</span><span class="cx"> {
</span><span class="cx">     Document* document;
</span><del>-    
</del><ins>+
</ins><span class="cx">     // FIXME: Do we want to expand this to all resource types that the mixed content checker would consider active content?
</span><span class="cx">     switch (type) {
</span><span class="cx">     case CachedResource::MainResource:
</span><span class="lines">@@ -624,7 +653,8 @@
</span><span class="cx"> 
</span><span class="cx">     prepareFetch(type, request);
</span><span class="cx"> 
</span><del>-    if (!canRequest(type, url, request.options(), request.forPreload())) {
</del><ins>+    // We are passing url as well as request, as request url may contain a fragment identifier.
+    if (!canRequest(type, url, request)) {
</ins><span class="cx">         RELEASE_LOG_IF_ALLOWED(&quot;requestResource: Not allowed to request resource (frame = %p)&quot;, frame());
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.h (206715 => 206716)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.h        2016-10-02 05:25:50 UTC (rev 206715)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.h        2016-10-02 13:59:18 UTC (rev 206716)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;CachedResource.h&quot;
</span><span class="cx"> #include &quot;CachedResourceHandle.h&quot;
</span><span class="cx"> #include &quot;CachedResourceRequest.h&quot;
</span><ins>+#include &quot;ContentSecurityPolicy.h&quot;
</ins><span class="cx"> #include &quot;ResourceLoadPriority.h&quot;
</span><span class="cx"> #include &quot;ResourceTimingInformation.h&quot;
</span><span class="cx"> #include &quot;Timer.h&quot;
</span><span class="lines">@@ -122,7 +123,7 @@
</span><span class="cx">     void loadDone(CachedResource*, bool shouldPerformPostLoadActions = true);
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void garbageCollectDocumentResources();
</span><del>-    
</del><ins>+
</ins><span class="cx">     void incrementRequestCount(const CachedResource&amp;);
</span><span class="cx">     void decrementRequestCount(const CachedResource&amp;);
</span><span class="cx">     int requestCount() const { return m_requestCount; }
</span><span class="lines">@@ -135,7 +136,8 @@
</span><span class="cx">     void checkForPendingPreloads();
</span><span class="cx">     void printPreloadStats();
</span><span class="cx"> 
</span><del>-    bool canRequest(CachedResource::Type, const URL&amp;, const ResourceLoaderOptions&amp;, bool forPreload = false, bool didReceiveRedirectResponse = false);
</del><ins>+    bool canRequest(CachedResource::Type, const URL&amp;, const CachedResourceRequest&amp;);
+    bool canRequestAfterRedirection(CachedResource::Type, const URL&amp;, const ResourceLoaderOptions&amp;);
</ins><span class="cx"> 
</span><span class="cx">     static const ResourceLoaderOptions&amp; defaultCachedResourceOptions();
</span><span class="cx"> 
</span><span class="lines">@@ -164,7 +166,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool shouldContinueAfterNotifyingLoadedFromMemoryCache(const CachedResourceRequest&amp;, CachedResource*);
</span><span class="cx">     bool checkInsecureContent(CachedResource::Type, const URL&amp;) const;
</span><del>-    bool allowedByContentSecurityPolicy(CachedResource::Type, const URL&amp;, const ResourceLoaderOptions&amp;, bool);
</del><ins>+    bool allowedByContentSecurityPolicy(CachedResource::Type, const URL&amp;, const ResourceLoaderOptions&amp;, ContentSecurityPolicy::RedirectResponseReceived);
</ins><span class="cx"> 
</span><span class="cx">     void performPostLoadActions();
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>