<!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>[230602] 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/230602">230602</a></dd>
<dt>Author</dt> <dd>dbates@webkit.org</dd>
<dt>Date</dt> <dd>2018-04-12 15:32:40 -0700 (Thu, 12 Apr 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>Content-Type not enforced for <script> allows for XSS
https://bugs.webkit.org/show_bug.cgi?id=184386
<rdar://problem/39112268>

Reviewed by Brady Eidson.

LayoutTests/imported/w3c:

Update expected result now that we pass all sub tests.

* web-platform-tests/fetch/api/basic/block-mime-as-script-expected.txt:

Source/WebCore:

As per the Fetch standard, <https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-mime-type?> (16 March 2018),
we should block JavaScript scripts that are served with MIME type text/csv, or a MIME type
that begins with "audio/", "image/" or "video/".

As a side benefit of this change we now set the destination property [1] on preload requests.

[1] <https://fetch.spec.whatwg.org/#concept-request-destination>

Tests: http/tests/security/script-with-banned-mimetype.html
       http/tests/workers/worker-importScripts-banned-mimetype.html

* Sources.txt: Add file FetchIdioms.cpp.
* WebCore.xcodeproj/project.pbxproj: Add files FetchIdioms.{cpp, h}.
* dom/LoadableClassicScript.cpp:
(WebCore::LoadableClassicScript::notifyFinished): Check the MIME type of the response and
block the script if applicable.
* dom/LoadableScript.h: Add error type MIMEType.
* loader/FetchIdioms.cpp: Added.
(WebCore::shouldBlockResponseDueToMIMEType): Implements the "Should response to request be blocked
due to its MIME type?" algorithm from the Fetch standard.
* loader/FetchIdioms.h: Added.
* loader/FetchOptions.h:
(WebCore::isScriptLikeDestination): Implements the definition of "script like" as per <https://fetch.spec.whatwg.org/#request-destination-script-like>.
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::requestImage): Removed logic to set the destination property as
CachedResourceLoader::requestResource() is now responsible for doing this.
(WebCore::CachedResourceLoader::requestFont): Ditto.
(WebCore::CachedResourceLoader::requestTextTrack): Ditto.
(WebCore::CachedResourceLoader::requestCSSStyleSheet): Ditto.
(WebCore::CachedResourceLoader::requestScript): Ditto.
(WebCore::CachedResourceLoader::requestXSLStyleSheet): Ditto.
(WebCore::CachedResourceLoader::requestMedia): Update comment to express that we should assert
that the destination property is either video or audio.
(WebCore::CachedResourceLoader::requestIcon): Remove logic to set the destination property as
CachedResourceLoader::requestResource() is now responsible for doing this.
(WebCore::CachedResourceLoader::requestRawResource): Removed assertion as this function is used to
load many kinds of requests that have different destination properties. The caller is responsible
for setting the appropriate destintion property.
(WebCore::CachedResourceLoader::requestMainResource): Remove logic to set the destination property
as CachedResourceLoader::requestResource() is now responsible for doing this.
(WebCore::destinationForType): Helper function that maps CachedResource::Type to FetchOptions::Destination.
(WebCore::CachedResourceLoader::requestResource): Set the destination property on the request if not
already set.
* loader/cache/CachedResourceLoader.h: Segregate requestRawResource() from the other request functions
and add a comment to explain what it is used for.
* workers/Worker.cpp:
(WebCore::Worker::create):
* workers/WorkerScriptLoader.cpp:
(WebCore::WorkerScriptLoader::loadSynchronously): Set the destination property to FetchOptions::Destination::Script
and store it in an instance variable as we will need to reference it once we receive the HTTP response.
Note that this function is only used to support the Web API importScripts().
(WebCore::WorkerScriptLoader::loadAsynchronously): Store the passed destination property in an
instance as we will need to reference it once we receive the HTTP response.
(WebCore::WorkerScriptLoader::didReceiveResponse): Check the MIME type of the response and
block the script if applicable.
* workers/WorkerScriptLoader.h:
* workers/service/ServiceWorkerJob.cpp:
(WebCore::ServiceWorkerJob::fetchScriptWithContext): Set the destination property to FetchOptions::Destination::Serviceworker.

LayoutTests:

Add tests to ensure that we block JavaScript scripts with a banned MIME type and update expected results.

Update tests http/tests/security/{cross-origin-cached-scripts, cross-origin-cached-scripts-parallel}.html
to load JavaScript scripts with MIME type text/javascript. These tests load JavaScript scripts indirectly
via the helper script LayoutTests/http/tests/security/resources/allow-if-origin.php. The script
allow-if-origin.php returns a response with MIME type image/png in absence of query string argument
contentType. We need to update these tests to pass contentType=text/javascript to allow-if-origin.php.

* TestExpectations: Mark test web-platform-tests/fetch/api/basic/block-mime-as-script.html DumpJSConsoleLogInStdErr
to ignore console message output when comparing the actual and expected result because the order the
sub tests are run is non-deterministic and the blocked MIME error message is specific to the blocked
response.
* http/tests/security/contentTypeOptions/invalid-content-type-options-allowed-expected.txt:
* http/tests/security/contentTypeOptions/invalid-content-type-options-allowed.html:
* http/tests/security/contentTypeOptions/resources/script-with-header.pl: Modified to only
set the HTTP header X-Content-Type-Options if the query argument no-content-type-options it
not present or evaluates to false in a boolean context. This lets us make use of this script
to test banned JavaScript MIME types.
* http/tests/security/cross-origin-cached-scripts-expected.txt:
* http/tests/security/cross-origin-cached-scripts-parallel-expected.txt:
* http/tests/security/cross-origin-cached-scripts-parallel.html:
* http/tests/security/cross-origin-cached-scripts.html:
* http/tests/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg: Added.
This file is both a valid JPEG image and a valid JavaScript script. When interpreted as a JavaScript
script it will increment the global variable self.scriptsSuccessfullyLoaded (defining it if
not already defined).
* http/tests/security/script-with-banned-mimetype-expected.txt: Added.
* http/tests/security/script-with-banned-mimetype.html: Added.
* http/tests/workers/resources/worker-importScripts-banned-mimetype.php: Added.
* http/tests/workers/worker-importScripts-banned-mimetype-expected.txt: Added.
* http/tests/workers/worker-importScripts-banned-mimetype.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsTestExpectations">trunk/LayoutTests/TestExpectations</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycontentTypeOptionsinvalidcontenttypeoptionsallowedexpectedtxt">trunk/LayoutTests/http/tests/security/contentTypeOptions/invalid-content-type-options-allowed-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycontentTypeOptionsinvalidcontenttypeoptionsallowedhtml">trunk/LayoutTests/http/tests/security/contentTypeOptions/invalid-content-type-options-allowed.html</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycontentTypeOptionsresourcesscriptwithheaderpl">trunk/LayoutTests/http/tests/security/contentTypeOptions/resources/script-with-header.pl</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycrossorigincachedscriptsexpectedtxt">trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycrossorigincachedscriptsparallelexpectedtxt">trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycrossorigincachedscriptsparallelhtml">trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel.html</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycrossorigincachedscriptshtml">trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts.html</a></li>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsfetchapibasicblockmimeasscriptexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/block-mime-as-script-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomLoadableClassicScriptcpp">trunk/Source/WebCore/dom/LoadableClassicScript.cpp</a></li>
<li><a href="#trunkSourceWebCoredomLoadableScripth">trunk/Source/WebCore/dom/LoadableScript.h</a></li>
<li><a href="#trunkSourceWebCoreloaderFetchOptionsh">trunk/Source/WebCore/loader/FetchOptions.h</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>
<li><a href="#trunkSourceWebCoreworkersWorkercpp">trunk/Source/WebCore/workers/Worker.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersWorkerScriptLoadercpp">trunk/Source/WebCore/workers/WorkerScriptLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersWorkerScriptLoaderh">trunk/Source/WebCore/workers/WorkerScriptLoader.h</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceServiceWorkerJobcpp">trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestssecurityresourcesabethatincrementsscriptsSuccessfullyLoadedjpg">trunk/LayoutTests/http/tests/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg</a></li>
<li><a href="#trunkLayoutTestshttptestssecurityscriptwithbannedmimetypeexpectedtxt">trunk/LayoutTests/http/tests/security/script-with-banned-mimetype-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecurityscriptwithbannedmimetypehtml">trunk/LayoutTests/http/tests/security/script-with-banned-mimetype.html</a></li>
<li><a href="#trunkLayoutTestshttptestsworkersresourcesworkerimportScriptsbannedmimetypephp">trunk/LayoutTests/http/tests/workers/resources/worker-importScripts-banned-mimetype.php</a></li>
<li><a href="#trunkLayoutTestshttptestsworkersworkerimportScriptsbannedmimetypeexpectedtxt">trunk/LayoutTests/http/tests/workers/worker-importScripts-banned-mimetype-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsworkersworkerimportScriptsbannedmimetypehtml">trunk/LayoutTests/http/tests/workers/worker-importScripts-banned-mimetype.html</a></li>
<li><a href="#trunkSourceWebCoreloaderFetchIdiomscpp">trunk/Source/WebCore/loader/FetchIdioms.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderFetchIdiomsh">trunk/Source/WebCore/loader/FetchIdioms.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/ChangeLog 2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2018-04-12  Daniel Bates  <dabates@apple.com>
+
+        Content-Type not enforced for <script> allows for XSS
+        https://bugs.webkit.org/show_bug.cgi?id=184386
+        <rdar://problem/39112268>
+
+        Reviewed by Brady Eidson.
+
+        Add tests to ensure that we block JavaScript scripts with a banned MIME type and update expected results.
+
+        Update tests http/tests/security/{cross-origin-cached-scripts, cross-origin-cached-scripts-parallel}.html
+        to load JavaScript scripts with MIME type text/javascript. These tests load JavaScript scripts indirectly
+        via the helper script LayoutTests/http/tests/security/resources/allow-if-origin.php. The script
+        allow-if-origin.php returns a response with MIME type image/png in absence of query string argument
+        contentType. We need to update these tests to pass contentType=text/javascript to allow-if-origin.php.
+
+        * TestExpectations: Mark test web-platform-tests/fetch/api/basic/block-mime-as-script.html DumpJSConsoleLogInStdErr
+        to ignore console message output when comparing the actual and expected result because the order the
+        sub tests are run is non-deterministic and the blocked MIME error message is specific to the blocked
+        response.
+        * http/tests/security/contentTypeOptions/invalid-content-type-options-allowed-expected.txt:
+        * http/tests/security/contentTypeOptions/invalid-content-type-options-allowed.html:
+        * http/tests/security/contentTypeOptions/resources/script-with-header.pl: Modified to only
+        set the HTTP header X-Content-Type-Options if the query argument no-content-type-options it
+        not present or evaluates to false in a boolean context. This lets us make use of this script
+        to test banned JavaScript MIME types.
+        * http/tests/security/cross-origin-cached-scripts-expected.txt:
+        * http/tests/security/cross-origin-cached-scripts-parallel-expected.txt:
+        * http/tests/security/cross-origin-cached-scripts-parallel.html:
+        * http/tests/security/cross-origin-cached-scripts.html:
+        * http/tests/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg: Added.
+        This file is both a valid JPEG image and a valid JavaScript script. When interpreted as a JavaScript
+        script it will increment the global variable self.scriptsSuccessfullyLoaded (defining it if
+        not already defined).
+        * http/tests/security/script-with-banned-mimetype-expected.txt: Added.
+        * http/tests/security/script-with-banned-mimetype.html: Added.
+        * http/tests/workers/resources/worker-importScripts-banned-mimetype.php: Added.
+        * http/tests/workers/worker-importScripts-banned-mimetype-expected.txt: Added.
+        * http/tests/workers/worker-importScripts-banned-mimetype.html: Added.
+
</ins><span class="cx"> 2018-04-12  Antoine Quint  <graouts@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Web Animations] Fix a host of small CSS Animations and CSS Transitions issues
</span></span></pre></div>
<a id="trunkLayoutTestsTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/TestExpectations (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/TestExpectations       2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/TestExpectations  2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -608,6 +608,7 @@
</span><span class="cx"> # Failing assertion with dynamic message
</span><span class="cx"> imported/w3c/web-platform-tests/XMLHttpRequest/responsexml-document-properties.htm [ Failure ]
</span><span class="cx"> 
</span><ins>+imported/w3c/web-platform-tests/fetch/api/basic/block-mime-as-script.html [ DumpJSConsoleLogInStdErr ]
</ins><span class="cx"> imported/w3c/web-platform-tests/fetch/api/cors/cors-origin.any.html [ DumpJSConsoleLogInStdErr ]
</span><span class="cx"> imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-status.any.html [ DumpJSConsoleLogInStdErr ]
</span><span class="cx"> imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight.any.html [ DumpJSConsoleLogInStdErr ]
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycontentTypeOptionsinvalidcontenttypeoptionsallowedexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/contentTypeOptions/invalid-content-type-options-allowed-expected.txt (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/contentTypeOptions/invalid-content-type-options-allowed-expected.txt       2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/http/tests/security/contentTypeOptions/invalid-content-type-options-allowed-expected.txt  2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -1,5 +1,4 @@
</span><span class="cx"> CONSOLE MESSAGE: line 2: Executed script with MIME type: 'application/json'.
</span><del>-CONSOLE MESSAGE: line 2: Executed script with MIME type: 'image/png'.
</del><span class="cx"> CONSOLE MESSAGE: line 2: Executed script with MIME type: 'text/html'.
</span><span class="cx"> CONSOLE MESSAGE: line 2: Executed script with MIME type: 'text/vbs'.
</span><span class="cx"> CONSOLE MESSAGE: line 2: Executed script with MIME type: 'text/vbscript'.
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycontentTypeOptionsinvalidcontenttypeoptionsallowedhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/contentTypeOptions/invalid-content-type-options-allowed.html (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/contentTypeOptions/invalid-content-type-options-allowed.html       2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/http/tests/security/contentTypeOptions/invalid-content-type-options-allowed.html  2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -10,7 +10,6 @@
</span><span class="cx"> 
</span><span class="cx">         var unscriptyMimeTypes = [
</span><span class="cx">             'application/json',
</span><del>-            'image/png',
</del><span class="cx">             'text/html',
</span><span class="cx">             'text/vbs',
</span><span class="cx">             'text/vbscript',
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycontentTypeOptionsresourcesscriptwithheaderpl"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/contentTypeOptions/resources/script-with-header.pl (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/contentTypeOptions/resources/script-with-header.pl 2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/http/tests/security/contentTypeOptions/resources/script-with-header.pl    2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -7,10 +7,12 @@
</span><span class="cx"> if ($cgi->param('mime')) {
</span><span class="cx">     print "Content-Type: " . $cgi->param('mime') . "\n";
</span><span class="cx"> }
</span><del>-if ($cgi->param('options')) {
-    print "X-Content-Type-Options: " . $cgi->param('options') . "\n";
-} else {
-    print "X-Content-Type-Options: nosniff\n";
</del><ins>+if (!$cgi->param('no-content-type-options')) {
+       if ($cgi->param('options')) {
+           print "X-Content-Type-Options: " . $cgi->param('options') . "\n";
+       } else {
+           print "X-Content-Type-Options: nosniff\n";
+       }
</ins><span class="cx"> }
</span><span class="cx"> print "\n";
</span><span class="cx"> print "if (self.console)\n";
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycrossorigincachedscriptsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-expected.txt (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-expected.txt   2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-expected.txt      2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -5,12 +5,12 @@
</span><span class="cx"> Tests source origin difference for cached resources.
</span><span class="cx"> 
</span><span class="cx"> Trying to load sequentially the same script from different origins.
</span><del>-Test 1 PASS: Loaded script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js from localhost:8000 (crossOrigin=anonymous)
-Test 2 PASS: Did not load script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js from localhost:8080 (crossOrigin=anonymous)
-Test 3 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js from localhost:8080
-Test 4 PASS: Did not load script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js from localhost:8080 (crossOrigin=anonymous)
-Test 5 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=*&name=notify-loaded.js from localhost:8000 (crossOrigin=anonymous)
-Test 6 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=*&name=notify-loaded.js from localhost:8080 (crossOrigin=anonymous)
</del><ins>+Test 1 PASS: Loaded script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&contentType=text/javascript from localhost:8000 (crossOrigin=anonymous)
+Test 2 PASS: Did not load script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&contentType=text/javascript from localhost:8080 (crossOrigin=anonymous)
+Test 3 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&contentType=text/javascript from localhost:8080
+Test 4 PASS: Did not load script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&contentType=text/javascript from localhost:8080 (crossOrigin=anonymous)
+Test 5 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=*&name=notify-loaded.js&contentType=text/javascript from localhost:8000 (crossOrigin=anonymous)
+Test 6 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=*&name=notify-loaded.js&contentType=text/javascript from localhost:8080 (crossOrigin=anonymous)
</ins><span class="cx">   
</span><span class="cx">   
</span><span class="cx">   
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycrossorigincachedscriptsparallelexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel-expected.txt (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel-expected.txt  2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel-expected.txt     2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -5,9 +5,9 @@
</span><span class="cx"> Tests source origin difference for cached resources.
</span><span class="cx"> 
</span><span class="cx"> Trying to load sequentially the same script from various origins.
</span><del>-Test 1 PASS: Loaded script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000 from localhost:8000 (crossOrigin=anonymous)
-Test 2 PASS: Did not load script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000 from localhost:8080 (crossOrigin=anonymous)
-Test 3 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000 from localhost:8080
-Test 4 PASS: Did not load script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000 from localhost:8080 (crossOrigin=anonymous)
</del><ins>+Test 1 PASS: Loaded script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000&contentType=text/javascript from localhost:8000 (crossOrigin=anonymous)
+Test 2 PASS: Did not load script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000&contentType=text/javascript from localhost:8080 (crossOrigin=anonymous)
+Test 3 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000&contentType=text/javascript from localhost:8080
+Test 4 PASS: Did not load script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000&contentType=text/javascript from localhost:8080 (crossOrigin=anonymous)
</ins><span class="cx">   
</span><span class="cx">   
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycrossorigincachedscriptsparallelhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel.html (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel.html  2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel.html     2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -36,8 +36,8 @@
</span><span class="cx"> var iframeURL8000 = "http://localhost:8000/security/resources/cross-origin-cached-resource-iframe.html";
</span><span class="cx"> var iframeURL8080 = "http://localhost:8080/security/resources/cross-origin-cached-resource-iframe.html";
</span><span class="cx"> 
</span><del>-var allow8000Script1 = "http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000";
-var allow8000Script2 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000";
</del><ins>+var allow8000Script1 = "http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000&contentType=text/javascript";
+var allow8000Script2 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=1000&contentType=text/javascript";
</ins><span class="cx"> 
</span><span class="cx"> function firstTest()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycrossorigincachedscriptshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts.html (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts.html   2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/http/tests/security/cross-origin-cached-scripts.html      2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -29,9 +29,9 @@
</span><span class="cx"> var iframeURL8000 = "http://localhost:8000/security/resources/cross-origin-cached-resource-iframe.html";
</span><span class="cx"> var iframeURL8080 = "http://localhost:8080/security/resources/cross-origin-cached-resource-iframe.html";
</span><span class="cx"> 
</span><del>-var allow8000Script1 = "http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js";
-var allow8000Script2 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js";
-var allow8000Script3 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=*&name=notify-loaded.js";
</del><ins>+var allow8000Script1 = "http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&contentType=text/javascript";
+var allow8000Script2 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&contentType=text/javascript";
+var allow8000Script3 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=*&name=notify-loaded.js&contentType=text/javascript";
</ins><span class="cx"> 
</span><span class="cx"> var counter = 0;
</span><span class="cx"> function loadNextFrame()
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityresourcesabethatincrementsscriptsSuccessfullyLoadedjpg"></a>
<div class="binary"><h4>Added: trunk/LayoutTests/http/tests/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: trunk/LayoutTests/http/tests/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg
</span><span class="cx">===================================================================
</span><del>--- trunk/LayoutTests/http/tests/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg   2018-04-12 22:03:34 UTC (rev 230601)
</del><ins>+++ trunk/LayoutTests/http/tests/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg    2018-04-12 22:32:40 UTC (rev 230602)
</ins><span class="cx">Property changes on: trunk/LayoutTests/http/tests/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/jpeg
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkLayoutTestshttptestssecurityscriptwithbannedmimetypeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/script-with-banned-mimetype-expected.txt (0 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/script-with-banned-mimetype-expected.txt                           (rev 0)
+++ trunk/LayoutTests/http/tests/security/script-with-banned-mimetype-expected.txt      2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=audio/mp4&no-content-type-options=1 as script because audio/mp4 is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=audio/mpeg&no-content-type-options=1 as script because audio/mpeg is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=audio/ogg&no-content-type-options=1 as script because audio/ogg is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=audio/wav&no-content-type-options=1 as script because audio/wav is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=audio/x-aiff&no-content-type-options=1 as script because audio/x-aiff is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=image/gif&no-content-type-options=1 as script because image/gif is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=image/png&no-content-type-options=1 as script because image/png is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=text/csv&no-content-type-options=1 as script because text/csv is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=video/mpeg&no-content-type-options=1 as script because video/mpeg is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=video/ogg&no-content-type-options=1 as script because video/ogg is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/contentTypeOptions/resources/script-with-header.pl?mime=video/quicktime&no-content-type-options=1 as script because video/quicktime is not a script MIME type.
+CONSOLE MESSAGE: Refused to execute http://127.0.0.1:8000/security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg as script because image/jpeg is not a script MIME type.
+Test that an external JavaScript script is blocked if it has a banned MIME type.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.scriptsSuccessfullyLoaded is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestssecurityscriptwithbannedmimetypehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/script-with-banned-mimetype.html (0 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/script-with-banned-mimetype.html                           (rev 0)
+++ trunk/LayoutTests/http/tests/security/script-with-banned-mimetype.html      2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+window.jsTestIsAsync = true;
+
+description("Test that an external JavaScript script is blocked if it has a banned MIME type.");
+
+// This is not a comprehensive list.
+var bannedMIMETypes = [
+    "audio/mp4",
+    "audio/mpeg",
+    "audio/ogg",
+    "audio/wav",
+    "audio/x-aiff",
+    "image/gif",
+    "image/png",
+    "text/csv",
+    "video/mpeg",
+    "video/ogg",
+    "video/quicktime",
+];
+
+window.scriptsSuccessfullyLoaded = 0;
+
+for (let mimeType of bannedMIMETypes)
+    document.write(`<script src="contentTypeOptions/resources/script-with-header.pl?mime=${mimeType}&no-content-type-options=1"><` + "/script>");
+
+document.write('<script src="resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg"><' + "/script>");
+
+window.onload = function () {
+    shouldBeZero("window.scriptsSuccessfullyLoaded");
+    finishJSTest();
+};
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersresourcesworkerimportScriptsbannedmimetypephp"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/workers/resources/worker-importScripts-banned-mimetype.php (0 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/resources/worker-importScripts-banned-mimetype.php                          (rev 0)
+++ trunk/LayoutTests/http/tests/workers/resources/worker-importScripts-banned-mimetype.php     2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+<?php
+header("Content-Type: text/javascript; charset=UTF-8");
+?>
+importScripts("/js-test-resources/js-test.js");
+
+// This is not a comprehensive list.
+var bannedMIMETypes = [
+    "audio/mp4",
+    "audio/mpeg",
+    "audio/ogg",
+    "audio/wav",
+    "audio/x-aiff",
+    "image/gif",
+    "image/png",
+    "text/csv",
+    "video/mpeg",
+    "video/ogg",
+    "video/quicktime",
+];
+
+self.scriptsSuccessfullyLoaded = 0;
+
+description("Test that an external JavaScript script is blocked if has a banned MIME type.");
+
+for (let mimeType of bannedMIMETypes) {
+    try {
+        importScripts(`../../security/contentTypeOptions/resources/script-with-header.pl?mime=${mimeType}&no-content-type-options=1`);
+    } catch (e) { }
+}
+
+try {
+    // For some reason this causes "SyntaxError: Invalid character '\ufffd'" when non-script MIME types are allowed to be executed.
+    importScripts("../../security/resources/abe-that-increments-scriptsSuccessfullyLoaded.jpg");
+} catch (e) { }
+
+shouldBeZero("self.scriptsSuccessfullyLoaded");
+finishJSTest();
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersworkerimportScriptsbannedmimetypeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/workers/worker-importScripts-banned-mimetype-expected.txt (0 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/worker-importScripts-banned-mimetype-expected.txt                           (rev 0)
+++ trunk/LayoutTests/http/tests/workers/worker-importScripts-banned-mimetype-expected.txt      2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+[Worker] Test that an external JavaScript script is blocked if has a banned MIME type.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Starting worker: resources/worker-importScripts-banned-mimetype.php
+PASS [Worker] self.scriptsSuccessfullyLoaded is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersworkerimportScriptsbannedmimetypehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/workers/worker-importScripts-banned-mimetype.html (0 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/worker-importScripts-banned-mimetype.html                           (rev 0)
+++ trunk/LayoutTests/http/tests/workers/worker-importScripts-banned-mimetype.html      2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+startWorker("resources/worker-importScripts-banned-mimetype.php");
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog 2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/imported/w3c/ChangeLog    2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2018-04-12  Daniel Bates  <dabates@apple.com>
+
+        Content-Type not enforced for <script> allows for XSS
+        https://bugs.webkit.org/show_bug.cgi?id=184386
+        <rdar://problem/39112268>
+
+        Reviewed by Brady Eidson.
+
+        Update expected result now that we pass all sub tests.
+
+        * web-platform-tests/fetch/api/basic/block-mime-as-script-expected.txt:
+
</ins><span class="cx"> 2018-04-12  Antoine Quint  <graouts@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Web Animations] Only cancel declarative animations upon element removal
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsfetchapibasicblockmimeasscriptexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/block-mime-as-script-expected.txt (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/block-mime-as-script-expected.txt      2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/block-mime-as-script-expected.txt 2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -1,36 +1,24 @@
</span><del>-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
-CONSOLE MESSAGE: line 1: Script loaded
</del><span class="cx"> 
</span><del>-FAIL Should fail loading non-empty script with text/csv MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with audio/aiff MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with audio/midi MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with audio/whatever MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with video/avi MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with video/fli MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with video/whatever MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with image/jpeg MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with image/gif MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading non-empty script with image/whatever MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with text/csv MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with audio/aiff MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with audio/midi MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with audio/whatever MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with video/avi MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with video/fli MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with video/whatever MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with image/jpeg MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with image/gif MIME type assert_unreached: Unexpected load event Reached unreachable code
-FAIL Should fail loading empty script with image/whatever MIME type assert_unreached: Unexpected load event Reached unreachable code
</del><ins>+PASS Should fail loading non-empty script with text/csv MIME type 
+PASS Should fail loading non-empty script with audio/aiff MIME type 
+PASS Should fail loading non-empty script with audio/midi MIME type 
+PASS Should fail loading non-empty script with audio/whatever MIME type 
+PASS Should fail loading non-empty script with video/avi MIME type 
+PASS Should fail loading non-empty script with video/fli MIME type 
+PASS Should fail loading non-empty script with video/whatever MIME type 
+PASS Should fail loading non-empty script with image/jpeg MIME type 
+PASS Should fail loading non-empty script with image/gif MIME type 
+PASS Should fail loading non-empty script with image/whatever MIME type 
+PASS Should fail loading empty script with text/csv MIME type 
+PASS Should fail loading empty script with audio/aiff MIME type 
+PASS Should fail loading empty script with audio/midi MIME type 
+PASS Should fail loading empty script with audio/whatever MIME type 
+PASS Should fail loading empty script with video/avi MIME type 
+PASS Should fail loading empty script with video/fli MIME type 
+PASS Should fail loading empty script with video/whatever MIME type 
+PASS Should fail loading empty script with image/jpeg MIME type 
+PASS Should fail loading empty script with image/gif MIME type 
+PASS Should fail loading empty script with image/whatever MIME type 
</ins><span class="cx"> PASS Should load script with text/html MIME type 
</span><span class="cx"> PASS Should load script with text/plain MIME type 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/ChangeLog      2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -1,3 +1,70 @@
</span><ins>+2018-04-12  Daniel Bates  <dabates@apple.com>
+
+        Content-Type not enforced for <script> allows for XSS
+        https://bugs.webkit.org/show_bug.cgi?id=184386
+        <rdar://problem/39112268>
+
+        Reviewed by Brady Eidson.
+
+        As per the Fetch standard, <https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-mime-type?> (16 March 2018),
+        we should block JavaScript scripts that are served with MIME type text/csv, or a MIME type
+        that begins with "audio/", "image/" or "video/".
+
+        As a side benefit of this change we now set the destination property [1] on preload requests.
+
+        [1] <https://fetch.spec.whatwg.org/#concept-request-destination>
+
+        Tests: http/tests/security/script-with-banned-mimetype.html
+               http/tests/workers/worker-importScripts-banned-mimetype.html
+
+        * Sources.txt: Add file FetchIdioms.cpp.
+        * WebCore.xcodeproj/project.pbxproj: Add files FetchIdioms.{cpp, h}.
+        * dom/LoadableClassicScript.cpp:
+        (WebCore::LoadableClassicScript::notifyFinished): Check the MIME type of the response and
+        block the script if applicable.
+        * dom/LoadableScript.h: Add error type MIMEType.
+        * loader/FetchIdioms.cpp: Added.
+        (WebCore::shouldBlockResponseDueToMIMEType): Implements the "Should response to request be blocked
+        due to its MIME type?" algorithm from the Fetch standard.
+        * loader/FetchIdioms.h: Added.
+        * loader/FetchOptions.h:
+        (WebCore::isScriptLikeDestination): Implements the definition of "script like" as per <https://fetch.spec.whatwg.org/#request-destination-script-like>.
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::CachedResourceLoader::requestImage): Removed logic to set the destination property as
+        CachedResourceLoader::requestResource() is now responsible for doing this.
+        (WebCore::CachedResourceLoader::requestFont): Ditto.
+        (WebCore::CachedResourceLoader::requestTextTrack): Ditto.
+        (WebCore::CachedResourceLoader::requestCSSStyleSheet): Ditto.
+        (WebCore::CachedResourceLoader::requestScript): Ditto.
+        (WebCore::CachedResourceLoader::requestXSLStyleSheet): Ditto.
+        (WebCore::CachedResourceLoader::requestMedia): Update comment to express that we should assert
+        that the destination property is either video or audio.
+        (WebCore::CachedResourceLoader::requestIcon): Remove logic to set the destination property as
+        CachedResourceLoader::requestResource() is now responsible for doing this.
+        (WebCore::CachedResourceLoader::requestRawResource): Removed assertion as this function is used to
+        load many kinds of requests that have different destination properties. The caller is responsible
+        for setting the appropriate destintion property.
+        (WebCore::CachedResourceLoader::requestMainResource): Remove logic to set the destination property
+        as CachedResourceLoader::requestResource() is now responsible for doing this.
+        (WebCore::destinationForType): Helper function that maps CachedResource::Type to FetchOptions::Destination.
+        (WebCore::CachedResourceLoader::requestResource): Set the destination property on the request if not
+        already set.
+        * loader/cache/CachedResourceLoader.h: Segregate requestRawResource() from the other request functions
+        and add a comment to explain what it is used for.
+        * workers/Worker.cpp:
+        (WebCore::Worker::create):
+        * workers/WorkerScriptLoader.cpp:
+        (WebCore::WorkerScriptLoader::loadSynchronously): Set the destination property to FetchOptions::Destination::Script
+        and store it in an instance variable as we will need to reference it once we receive the HTTP response.
+        Note that this function is only used to support the Web API importScripts().
+        (WebCore::WorkerScriptLoader::loadAsynchronously): Store the passed destination property in an
+        instance as we will need to reference it once we receive the HTTP response.
+        (WebCore::WorkerScriptLoader::didReceiveResponse): Check the MIME type of the response and
+        block the script if applicable.
+        * workers/WorkerScriptLoader.h:
+        * workers/service/ServiceWorkerJob.cpp:
+        (WebCore::ServiceWorkerJob::fetchScriptWithContext): Set the destination property to FetchOptions::Destination::Serviceworker.
+
</ins><span class="cx"> 2018-04-12  Antoine Quint  <graouts@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Web Animations] Fix a host of small CSS Animations and CSS Transitions issues
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Sources.txt 2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/Sources.txt    2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -1224,6 +1224,7 @@
</span><span class="cx"> loader/FrameLoadRequest.cpp
</span><span class="cx"> loader/FrameLoader.cpp
</span><span class="cx"> loader/FrameLoaderStateMachine.cpp
</span><ins>+loader/FetchIdioms.cpp
</ins><span class="cx"> loader/HTTPHeaderField.cpp
</span><span class="cx"> loader/HistoryController.cpp
</span><span class="cx"> loader/ImageLoader.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -4059,6 +4059,7 @@
</span><span class="cx">          CE7B2DB31586ABAD0098B3FA /* AlternativeTextUIController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DAF1586ABAD0098B3FA /* AlternativeTextUIController.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          CE7B2DB51586ABAD0098B3FA /* TextAlternativeWithRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          CE7E17831C83A49100AD06AF /* ContentSecurityPolicyHash.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7E17821C83A49100AD06AF /* ContentSecurityPolicyHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+               CEBB8C3320786DCB00039547 /* FetchIdioms.h in Headers */ = {isa = PBXBuildFile; fileRef = CEBB8C3120786DCB00039547 /* FetchIdioms.h */; };
</ins><span class="cx">           CECADFC7153778FF00E37068 /* DictationAlternative.h in Headers */ = {isa = PBXBuildFile; fileRef = CECADFC3153778FF00E37068 /* DictationAlternative.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          CECADFC9153778FF00E37068 /* DictationCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = CECADFC5153778FF00E37068 /* DictationCommand.h */; };
</span><span class="cx">          CECADFCE1537791D00E37068 /* TextInsertionBaseCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = CECADFCC1537791D00E37068 /* TextInsertionBaseCommand.h */; };
</span><span class="lines">@@ -13349,6 +13350,8 @@
</span><span class="cx">          CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextAlternativeWithRange.h; sourceTree = "<group>"; };
</span><span class="cx">          CE7B2DB21586ABAD0098B3FA /* TextAlternativeWithRange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextAlternativeWithRange.mm; sourceTree = "<group>"; };
</span><span class="cx">          CE7E17821C83A49100AD06AF /* ContentSecurityPolicyHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicyHash.h; path = csp/ContentSecurityPolicyHash.h; sourceTree = "<group>"; };
</span><ins>+               CEBB8C3120786DCB00039547 /* FetchIdioms.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FetchIdioms.h; sourceTree = "<group>"; };
+               CEBB8C3220786DCB00039547 /* FetchIdioms.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FetchIdioms.cpp; sourceTree = "<group>"; };
</ins><span class="cx">           CECADFC2153778FF00E37068 /* DictationAlternative.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DictationAlternative.cpp; sourceTree = "<group>"; };
</span><span class="cx">          CECADFC3153778FF00E37068 /* DictationAlternative.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DictationAlternative.h; sourceTree = "<group>"; };
</span><span class="cx">          CECADFC4153778FF00E37068 /* DictationCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DictationCommand.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -23909,6 +23912,8 @@
</span><span class="cx">                          F52AD5E31534245F0059FBE6 /* EmptyClients.cpp */,
</span><span class="cx">                          B255990D0D00D8B900BB825C /* EmptyClients.h */,
</span><span class="cx">                          414DEDE51F9FE9150047C40D /* EmptyFrameLoaderClient.h */,
</span><ins>+                               CEBB8C3220786DCB00039547 /* FetchIdioms.cpp */,
+                               CEBB8C3120786DCB00039547 /* FetchIdioms.h */,
</ins><span class="cx">                           41AD75391CEF6BCE00A31486 /* FetchOptions.h */,
</span><span class="cx">                          656D37230ADBA5DE00A4554D /* FormState.cpp */,
</span><span class="cx">                          656D37220ADBA5DE00A4554D /* FormState.h */,
</span><span class="lines">@@ -27534,6 +27539,7 @@
</span><span class="cx">                          517A535B1F588A4C00DCDC0A /* FetchBodyConsumer.h in Headers */,
</span><span class="cx">                          4129C9971F59B963009D7403 /* FetchBodySource.h in Headers */,
</span><span class="cx">                          41D129DB1F3D143800D15E47 /* FetchHeaders.h in Headers */,
</span><ins>+                               CEBB8C3320786DCB00039547 /* FetchIdioms.h in Headers */,
</ins><span class="cx">                           4161E2D51FE48DC500EC2E96 /* FetchLoader.h in Headers */,
</span><span class="cx">                          517A53581F5889E800DCDC0A /* FetchLoaderClient.h in Headers */,
</span><span class="cx">                          41AD753A1CEF6BD100A31486 /* FetchOptions.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCoredomLoadableClassicScriptcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/LoadableClassicScript.cpp (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/LoadableClassicScript.cpp       2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/dom/LoadableClassicScript.cpp  2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "LoadableClassicScript.h"
</span><span class="cx"> 
</span><ins>+#include "FetchIdioms.h"
</ins><span class="cx"> #include "ScriptElement.h"
</span><span class="cx"> #include "ScriptSourceCode.h"
</span><span class="cx"> #include "SubresourceIntegrity.h"
</span><span class="lines">@@ -95,6 +96,17 @@
</span><span class="cx">         };
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (!m_error && shouldBlockResponseDueToMIMEType(m_cachedScript->response(), m_cachedScript->options().destination)) {
+        m_error = Error {
+            ErrorType::MIMEType,
+            ConsoleMessage {
+                MessageSource::Security,
+                MessageLevel::Error,
+                makeString("Refused to execute ", m_cachedScript->url().stringCenterEllipsizedToLength(), " as script because ", m_cachedScript->response().mimeType(), " is not a script MIME type.")
+            }
+        };
+    }
+
</ins><span class="cx">     if (!m_error && !resource.errorOccurred() && !matchIntegrityMetadata(resource, m_integrity)) {
</span><span class="cx">         m_error = Error {
</span><span class="cx">             ErrorType::FailedIntegrityCheck,
</span></span></pre></div>
<a id="trunkSourceWebCoredomLoadableScripth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/LoadableScript.h (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/LoadableScript.h        2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/dom/LoadableScript.h   2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx">     enum class ErrorType {
</span><span class="cx">         CachedScript,
</span><span class="cx">         CrossOriginLoad,
</span><ins>+        MIMEType,
</ins><span class="cx">         Nosniff,
</span><span class="cx">         FailedIntegrityCheck,
</span><span class="cx">     };
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFetchIdiomscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/loader/FetchIdioms.cpp (0 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FetchIdioms.cpp                              (rev 0)
+++ trunk/Source/WebCore/loader/FetchIdioms.cpp 2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FetchIdioms.h"
+
+#include "HTTPParsers.h"
+#include "ResourceResponse.h"
+
+namespace WebCore {
+
+bool shouldBlockResponseDueToMIMEType(const ResourceResponse& response, FetchOptions::Destination requestDestination)
+{
+    String mimeType = extractMIMETypeFromMediaType(response.httpHeaderField(HTTPHeaderName::ContentType));
+    return isScriptLikeDestination(requestDestination) && (startsWithLettersIgnoringASCIICase(mimeType, "audio/")
+        || startsWithLettersIgnoringASCIICase(mimeType, "image/") || startsWithLettersIgnoringASCIICase(mimeType, "video/")
+        || equalLettersIgnoringASCIICase(mimeType, "text/csv"));
+}
+
+} // namespace WebCore
+
</ins></span></pre></div>
<a id="trunkSourceWebCoreloaderFetchIdiomsh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/loader/FetchIdioms.h (0 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FetchIdioms.h                                (rev 0)
+++ trunk/Source/WebCore/loader/FetchIdioms.h   2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "FetchOptions.h"
+
+namespace WebCore {
+
+class ResourceResponse;
+
+// <https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-mime-type?>
+bool shouldBlockResponseDueToMIMEType(const ResourceResponse&, FetchOptions::Destination);
+
+} // namespace WebCore
+
</ins></span></pre></div>
<a id="trunkSourceWebCoreloaderFetchOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FetchOptions.h (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FetchOptions.h       2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/loader/FetchOptions.h  2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -88,8 +88,15 @@
</span><span class="cx">         || destination == FetchOptions::Destination::Worker;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool isScriptLikeDestination(FetchOptions::Destination destination)
+{
+    return destination == FetchOptions::Destination::Script
+        || destination == FetchOptions::Destination::Serviceworker
+        || destination == FetchOptions::Destination::Worker;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+}
+
</ins><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> template<> struct EnumTraits<WebCore::FetchOptions::Destination> {
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp       2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp  2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -197,7 +197,6 @@
</span><span class="cx"> 
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedImage>> CachedResourceLoader::requestImage(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    request.setDestinationIfNotSet(FetchOptions::Destination::Image);
</del><span class="cx">     if (Frame* frame = this->frame()) {
</span><span class="cx">         if (frame->loader().pageDismissalEventBeingDispatched() != FrameLoader::PageDismissalType::None) {
</span><span class="cx">             if (Document* document = frame->document())
</span><span class="lines">@@ -215,7 +214,6 @@
</span><span class="cx"> 
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedFont>> CachedResourceLoader::requestFont(CachedResourceRequest&& request, bool isSVG)
</span><span class="cx"> {
</span><del>-    request.setDestinationIfNotSet(FetchOptions::Destination::Font);
</del><span class="cx"> #if ENABLE(SVG_FONTS)
</span><span class="cx">     if (isSVG)
</span><span class="cx">         return castCachedResourceTo<CachedFont>(requestResource(CachedResource::SVGFontResource, WTFMove(request)));
</span><span class="lines">@@ -228,7 +226,6 @@
</span><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedTextTrack>> CachedResourceLoader::requestTextTrack(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    request.setDestinationIfNotSet(FetchOptions::Destination::Track);
</del><span class="cx">     return castCachedResourceTo<CachedTextTrack>(requestResource(CachedResource::TextTrackResource, WTFMove(request)));
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="lines">@@ -235,7 +232,6 @@
</span><span class="cx"> 
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedCSSStyleSheet>> CachedResourceLoader::requestCSSStyleSheet(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    request.setDestinationIfNotSet(FetchOptions::Destination::Style);
</del><span class="cx">     return castCachedResourceTo<CachedCSSStyleSheet>(requestResource(CachedResource::CSSStyleSheet, WTFMove(request)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -269,7 +265,6 @@
</span><span class="cx"> 
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedScript>> CachedResourceLoader::requestScript(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    request.setDestinationIfNotSet(FetchOptions::Destination::Script);
</del><span class="cx">     return castCachedResourceTo<CachedScript>(requestResource(CachedResource::Script, WTFMove(request)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -276,7 +271,6 @@
</span><span class="cx"> #if ENABLE(XSLT)
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedXSLStyleSheet>> CachedResourceLoader::requestXSLStyleSheet(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    request.setDestinationIfNotSet(FetchOptions::Destination::Xslt);
</del><span class="cx">     return castCachedResourceTo<CachedXSLStyleSheet>(requestResource(CachedResource::XSLStyleSheet, WTFMove(request)));
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="lines">@@ -295,19 +289,17 @@
</span><span class="cx"> 
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedRawResource>> CachedResourceLoader::requestMedia(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    // FIXME: Set destination to either audio or video.
</del><ins>+    // FIXME: Assert request.options().destination is FetchOptions::Destination::{Audio, Video}.
</ins><span class="cx">     return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::MediaResource, WTFMove(request)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedRawResource>> CachedResourceLoader::requestIcon(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    request.setDestinationIfNotSet(FetchOptions::Destination::Image);
</del><span class="cx">     return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::Icon, WTFMove(request)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedRawResource>> CachedResourceLoader::requestRawResource(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    ASSERT(request.options().destination == FetchOptions::Destination::EmptyString || request.options().serviceWorkersMode == ServiceWorkersMode::None);
</del><span class="cx">     return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::RawResource, WTFMove(request)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -319,7 +311,6 @@
</span><span class="cx"> 
</span><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedRawResource>> CachedResourceLoader::requestMainResource(CachedResourceRequest&& request)
</span><span class="cx"> {
</span><del>-    request.setDestinationIfNotSet(FetchOptions::Destination::Document);
</del><span class="cx">     return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::MainResource, WTFMove(request)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -738,8 +729,49 @@
</span><span class="cx">     request.updateAccordingCacheMode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static FetchOptions::Destination destinationForType(CachedResource::Type type)
+{
+    switch (type) {
+    case CachedResource::MainResource:
+    case CachedResource::SVGDocumentResource:
+        return FetchOptions::Destination::Document;
+    case CachedResource::ImageResource:
+    case CachedResource::Icon:
+        return FetchOptions::Destination::Image;
+    case CachedResource::CSSStyleSheet:
+        return FetchOptions::Destination::Style;
+    case CachedResource::Script:
+        return FetchOptions::Destination::Script;
+    case CachedResource::FontResource:
+#if ENABLE(SVG_FONTS)
+    case CachedResource::SVGFontResource:
+#endif
+        return FetchOptions::Destination::Font;
+#if ENABLE(XSLT)
+    case CachedResource::XSLStyleSheet:
+        return FetchOptions::Destination::Xslt;
+#endif
+#if ENABLE(VIDEO_TRACK)
+    case CachedResource::TextTrackResource:
+        return FetchOptions::Destination::Track;
+#endif
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        return FetchOptions::Destination::Manifest;
+#endif
+    case CachedResource::Beacon:
+    case CachedResource::LinkPrefetch:
+    case CachedResource::RawResource:
+    case CachedResource::MediaResource:
+        // The caller is responsible for setting the appropriate destination.
+        return FetchOptions::Destination::EmptyString;
+    }
+}
+
</ins><span class="cx"> ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest&& request, ForPreload forPreload, DeferOption defer)
</span><span class="cx"> {
</span><ins>+    request.setDestinationIfNotSet(destinationForType(type));
+
</ins><span class="cx">     // Entry point to https://fetch.spec.whatwg.org/#main-fetch.
</span><span class="cx">     std::unique_ptr<ResourceRequest> originalRequest;
</span><span class="cx">     if (CachedResource::shouldUsePingLoad(type))
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.h (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.h 2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.h    2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -87,7 +87,6 @@
</span><span class="cx">     ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestMedia(CachedResourceRequest&&);
</span><span class="cx">     ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestIcon(CachedResourceRequest&&);
</span><span class="cx">     ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestBeaconResource(CachedResourceRequest&&);
</span><del>-    ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestRawResource(CachedResourceRequest&&);
</del><span class="cx">     ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestMainResource(CachedResourceRequest&&);
</span><span class="cx">     ResourceErrorOr<CachedResourceHandle<CachedSVGDocument>> requestSVGDocument(CachedResourceRequest&&);
</span><span class="cx"> #if ENABLE(XSLT)
</span><span class="lines">@@ -101,6 +100,10 @@
</span><span class="cx">     ResourceErrorOr<CachedResourceHandle<CachedApplicationManifest>> requestApplicationManifest(CachedResourceRequest&&);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    // Called to load Web Worker main script, Service Worker main script, importScripts(), XHR,
+    // EventSource, Fetch, and App Cache.
+    ResourceErrorOr<CachedResourceHandle<CachedRawResource>> requestRawResource(CachedResourceRequest&&);
+
</ins><span class="cx">     // Logs an access denied message to the console for the specified URL.
</span><span class="cx">     void printAccessDeniedMessage(const URL& url) const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersWorkercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/Worker.cpp (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/Worker.cpp  2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/workers/Worker.cpp     2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -107,6 +107,7 @@
</span><span class="cx">     options.mode = FetchOptions::Mode::SameOrigin;
</span><span class="cx">     options.cache = FetchOptions::Cache::Default;
</span><span class="cx">     options.redirect = FetchOptions::Redirect::Follow;
</span><ins>+    options.destination = FetchOptions::Destination::Worker;
</ins><span class="cx">     worker->m_scriptLoader->loadAsynchronously(context, WTFMove(request), WTFMove(options), contentSecurityPolicyEnforcement, ServiceWorkersMode::All, worker);
</span><span class="cx">     return WTFMove(worker);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersWorkerScriptLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/WorkerScriptLoader.cpp (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/WorkerScriptLoader.cpp      2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/workers/WorkerScriptLoader.cpp 2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #include "WorkerScriptLoader.h"
</span><span class="cx"> 
</span><span class="cx"> #include "ContentSecurityPolicy.h"
</span><ins>+#include "FetchIdioms.h"
</ins><span class="cx"> #include "ResourceResponse.h"
</span><span class="cx"> #include "ScriptExecutionContext.h"
</span><span class="cx"> #include "ServiceWorker.h"
</span><span class="lines">@@ -49,6 +50,7 @@
</span><span class="cx">     auto& workerGlobalScope = downcast<WorkerGlobalScope>(*scriptExecutionContext);
</span><span class="cx"> 
</span><span class="cx">     m_url = url;
</span><ins>+    m_destination = FetchOptions::Destination::Script;
</ins><span class="cx"> 
</span><span class="cx">     std::unique_ptr<ResourceRequest> request(createResourceRequest(initiatorIdentifier));
</span><span class="cx">     if (!request)
</span><span class="lines">@@ -65,6 +67,7 @@
</span><span class="cx">     options.cache = cachePolicy;
</span><span class="cx">     options.sendLoadCallbacks = SendCallbacks;
</span><span class="cx">     options.contentSecurityPolicyEnforcement = contentSecurityPolicyEnforcement;
</span><ins>+    options.destination = m_destination;
</ins><span class="cx"> #if ENABLE(SERVICE_WORKER)
</span><span class="cx">     options.serviceWorkersMode = workerGlobalScope.isServiceWorkerGlobalScope() ? ServiceWorkersMode::None : ServiceWorkersMode::All;
</span><span class="cx">     if (auto* activeServiceWorker = workerGlobalScope.activeServiceWorker())
</span><span class="lines">@@ -77,6 +80,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_client = &client;
</span><span class="cx">     m_url = scriptRequest.url();
</span><ins>+    m_destination = fetchOptions.destination;
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(scriptRequest.httpMethod() == "GET");
</span><span class="cx"> 
</span><span class="lines">@@ -132,6 +136,13 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (shouldBlockResponseDueToMIMEType(response, m_destination)) {
+        String message = makeString("Refused to execute ", response.url().stringCenterEllipsizedToLength(), " as script because ", response.mimeType(), " is not a script MIME type.");
+        m_error = ResourceError { errorDomainWebKitInternal, 0, response.url(), message, ResourceError::Type::General };
+        m_failed = true;
+        return;
+    }
+
</ins><span class="cx">     m_responseURL = response.url();
</span><span class="cx">     m_responseMIMEType = response.mimeType();
</span><span class="cx">     m_responseEncoding = response.textEncodingName();
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersWorkerScriptLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/WorkerScriptLoader.h (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/WorkerScriptLoader.h        2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/workers/WorkerScriptLoader.h   2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include "ContentSecurityPolicyResponseHeaders.h"
</span><ins>+#include "FetchOptions.h"
</ins><span class="cx"> #include "ResourceError.h"
</span><span class="cx"> #include "ResourceRequest.h"
</span><span class="cx"> #include "ThreadableLoader.h"
</span><span class="lines">@@ -91,6 +92,7 @@
</span><span class="cx">     URL m_url;
</span><span class="cx">     URL m_responseURL;
</span><span class="cx">     String m_responseMIMEType;
</span><ins>+    FetchOptions::Destination m_destination;
</ins><span class="cx">     ContentSecurityPolicyResponseHeaders m_contentSecurityPolicy;
</span><span class="cx">     unsigned long m_identifier { 0 };
</span><span class="cx">     bool m_failed { false };
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceServiceWorkerJobcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp (230601 => 230602)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp        2018-04-12 22:03:34 UTC (rev 230601)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp   2018-04-12 22:32:40 UTC (rev 230602)
</span><span class="lines">@@ -102,6 +102,7 @@
</span><span class="cx">     options.mode = FetchOptions::Mode::SameOrigin;
</span><span class="cx">     options.cache = cachePolicy;
</span><span class="cx">     options.redirect = FetchOptions::Redirect::Error;
</span><ins>+    options.destination = FetchOptions::Destination::Serviceworker;
</ins><span class="cx">     m_scriptLoader->loadAsynchronously(context, WTFMove(request), WTFMove(options), ContentSecurityPolicyEnforcement::DoNotEnforce, ServiceWorkersMode::None, *this);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>