Index: third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/subresource-integrity.sub.html |
diff --git a/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/subresource-integrity.sub.html b/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/subresource-integrity.sub.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..89ae018e48e0b30789a61381f36a008e03550083 |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/subresource-integrity.sub.html |
@@ -0,0 +1,573 @@ |
+<!DOCTYPE html> |
+<meta charset=utf-8> |
+<title>Subresource Integrity</title> |
+<script src="/resources/testharness.js"></script> |
+<script src="/resources/testharnessreport.js"></script> |
+ |
+<div id="log"></div> |
+ |
+<div id="container"></div> |
+<script> |
+ // This horrible hack is needed for the 'use-credentials' tests because, on |
+ // response, if port 80 or 443 is the current port, it will not appear to |
+ // the browser as part of the origin string. Since the origin *string* is |
+ // used for CORS access control, instead of the origin itself, if there |
+ // isn't an exact string match, the check will fail. For example, |
+ // "http://example.com" would not match "http://example.com:80", because |
+ // they are not exact string matches, even though the origins are the same. |
+ // |
+ // Thus, we only want the Access-Control-Allow-Origin header to have |
+ // the port if it's not port 80 or 443, since the user agent will elide the |
+ // ports in those cases. |
+ var main_domain = "{{domains[]}}"; |
+ var www_domain = "{{domains[www]}}"; |
+ var default_port = "{{ports[http][0]}}"; |
+ if (location.protocol === "https:") { |
+ default_port = "{{ports[https][0]}}"; |
+ } |
+ |
+ var port_string = ""; |
+ if (default_port !== "80" && default_port !== "443") |
+ port_string = ":" + default_port; |
+ |
+ www_host_and_port = www_domain + port_string; |
+ |
+ // <script> tests |
+ var xorigin_anon_script = location.protocol |
+ + '//' + www_host_and_port |
+ + '/subresource-integrity/crossorigin-anon-script.js'; |
+ |
+ var xorigin_creds_script = location.protocol |
+ + '//' + www_host_and_port |
+ + '/subresource-integrity/crossorigin-creds-script.js?acao_port=' |
+ + port_string; |
+ |
+ var xorigin_ineligible_script = location.protocol |
+ + '//' + www_host_and_port |
+ + '/subresource-integrity/crossorigin-ineligible-script.js'; |
+ |
+ var SRIScriptTest = function(pass, name, src, integrityValue, crossoriginValue) { |
+ this.pass = pass; |
+ this.name = "Script: " + name; |
+ this.src = src; |
+ this.integrityValue = integrityValue; |
+ this.crossoriginValue = crossoriginValue; |
+ } |
+ |
+ SRIScriptTest.prototype.execute = function() { |
+ var test = async_test(this.name); |
+ var e = document.createElement("script"); |
+ e.src = this.src; |
+ e.setAttribute("integrity", this.integrityValue); |
+ if(this.crossoriginValue) { |
+ e.setAttribute("crossorigin", this.crossoriginValue); |
+ } |
+ if(this.pass) { |
+ e.addEventListener("load", function() {test.done()}); |
+ e.addEventListener("error", function() { |
+ test.step(function(){ assert_unreached("Good load fired error handler.") }) |
+ }); |
+ } else { |
+ e.addEventListener("load", function() { |
+ test.step(function() { assert_unreached("Bad load succeeded.") }) |
+ }); |
+ e.addEventListener("error", function() {test.done()}); |
+ } |
+ document.body.appendChild(e); |
+ }; |
+ |
+ // Note that all of these style URLs have query parameters started, so any |
+ // additional parameters should be appended starting with '&'. |
+ var xorigin_anon_style = location.protocol |
+ + '//' + www_host_and_port |
+ + '/subresource-integrity/crossorigin-anon-style.css?'; |
+ |
+ var xorigin_creds_style = location.protocol |
+ + '//' + www_host_and_port |
+ + '/subresource-integrity/crossorigin-creds-style.css?acao_port=' |
+ + port_string; |
+ |
+ var xorigin_ineligible_style = location.protocol |
+ + '//' + www_host_and_port |
+ + '/subresource-integrity/crossorigin-ineligible-style.css?'; |
+ |
+ // <link> tests |
+ // Style tests must be done synchronously because they rely on the presence |
+ // and absence of global style, which can affect later tests. Thus, instead |
+ // of executing them one at a time, the style tests are implemented as a |
+ // queue that builds up a list of tests, and then executes them one at a |
+ // time. |
+ var SRIStyleTest = function(queue, pass, name, attrs, customCallback, altPassValue) { |
+ this.pass = pass; |
+ this.name = "Style: " + name; |
+ this.customCallback = customCallback || function () {}; |
+ this.attrs = attrs || {}; |
+ this.passValue = altPassValue || "rgb(255, 255, 0)"; |
+ |
+ this.test = async_test(this.name); |
+ |
+ this.queue = queue; |
+ this.queue.push(this); |
+ } |
+ |
+ SRIStyleTest.prototype.execute = function() { |
+ var that = this; |
+ var container = document.getElementById("container"); |
+ while (container.hasChildNodes()) { |
+ container.removeChild(container.firstChild); |
+ } |
+ |
+ var test = this.test; |
+ |
+ var div = document.createElement("div"); |
+ div.className = "testdiv"; |
+ var e = document.createElement("link"); |
+ this.attrs.rel = this.attrs.rel || "stylesheet"; |
+ for (var key in this.attrs) { |
+ if (this.attrs.hasOwnProperty(key)) { |
+ e.setAttribute(key, this.attrs[key]); |
+ } |
+ } |
+ |
+ if(this.pass) { |
+ e.addEventListener("load", function() { |
+ test.step(function() { |
+ var background = window.getComputedStyle(div, null).getPropertyValue("background-color"); |
+ assert_equals(background, that.passValue); |
+ test.done(); |
+ }); |
+ }); |
+ e.addEventListener("error", function() { |
+ test.step(function(){ assert_unreached("Good load fired error handler.") }) |
+ }); |
+ } else { |
+ e.addEventListener("load", function() { |
+ test.step(function() { assert_unreached("Bad load succeeded.") }) |
+ }); |
+ e.addEventListener("error", function() { |
+ test.step(function() { |
+ var background = window.getComputedStyle(div, null).getPropertyValue("background-color"); |
+ assert_not_equals(background, that.passValue); |
+ test.done(); |
+ }); |
+ }); |
+ } |
+ container.appendChild(div); |
+ container.appendChild(e); |
+ this.customCallback(e, container); |
+ }; |
+ |
+ var style_tests = []; |
+ style_tests.execute = function() { |
+ if (this.length > 0) { |
+ this.shift().execute(); |
+ } |
+ } |
+ add_result_callback(function(res) { |
+ if (res.name.startsWith("Style: ")) { |
+ style_tests.execute(); |
+ } |
+ }); |
+ |
+ // Script tests |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with correct sha256 hash.", |
+ "matching-digest.js", |
+ "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with correct sha384 hash.", |
+ "matching-digest.js", |
+ "sha384-BDRTPSywZFyxfLEAzaLcL4FfERBgJgXfEkuT0r04LG93Yqn1PWNYPZMomaqEfE3H" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with correct sha512 hash.", |
+ "matching-digest.js", |
+ "sha512-geByvIIRspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg==" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with empty integrity.", |
+ "matching-digest.js", |
+ "" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ false, |
+ "Same-origin with incorrect hash.", |
+ "non-matching-digest.js", |
+ "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with multiple sha256 hashes, including correct.", |
+ "matching-digest.js", |
+ "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with multiple sha256 hashes, including unknown algorithm.", |
+ "matching-digest.js", |
+ "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with sha256 mismatch, sha512 match", |
+ "matching-digest.js", |
+ "sha512-geByvIIRspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ false, |
+ "Same-origin with sha256 match, sha512 mismatch", |
+ "matching-digest.js", |
+ "sha512-deadbeefspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "<crossorigin='anonymous'> with correct hash, ACAO: *", |
+ xorigin_anon_script, |
+ "sha256-51AjITq701Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=", |
+ "anonymous" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ false, |
+ "<crossorigin='anonymous'> with incorrect hash, ACAO: *", |
+ xorigin_anon_script, |
+ "sha256-deadbeefcSLlbFZCj1OACLxTxVck2TOrBTEdUbwz1yU=", |
+ "anonymous" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "<crossorigin='use-credentials'> with correct hash, CORS-eligible", |
+ xorigin_creds_script, |
+ "sha256-IaGApVboXPQxVSm2wVFmhMq1Yu37gWklajgMdxKLIvc=", |
+ "use-credentials" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ false, |
+ "<crossorigin='use-credentials'> with incorrect hash CORS-eligible", |
+ xorigin_creds_script, |
+ "sha256-deadbeef2S+pTRZgiw3DWrhC6JLDlt2zRyGpwH7unU8=", |
+ "use-credentials" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ false, |
+ "<crossorigin='anonymous'> with CORS-ineligible resource", |
+ xorigin_ineligible_script, |
+ "sha256-F5fXKTX7SiWjtgybxiBZIo2qhh2WiQnNx372E60XrOo=", |
+ "anonymous" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ false, |
+ "Cross-origin, not CORS request, with correct hash", |
+ xorigin_anon_script, |
+ "sha256-51AjITq701Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ false, |
+ "Cross-origin, not CORS request, with hash mismatch", |
+ xorigin_anon_script, |
+ "sha256-deadbeef01Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Cross-origin, empty integrity", |
+ xorigin_anon_script, |
+ "" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with correct hash, options.", |
+ "matching-digest.js", |
+ "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=?foo=bar?spam=eggs" |
+ ).execute(); |
+ |
+ new SRIScriptTest( |
+ true, |
+ "Same-origin with unknown algorithm only.", |
+ "matching-digest.js", |
+ "foo666-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=" |
+ ).execute(); |
+ |
+ // Style tests |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with correct sha256 hash", |
+ { |
+ href: "style.css?1", |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with correct sha384 hash", |
+ { |
+ href: "style.css?2", |
+ integrity: "sha384-wDAWxH4tOWBwAwHfBn9B7XuNmFxHTMeigAMwn0iVQ0zq3FtmYMLxihcGnU64CwcX" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with correct sha512 hash", |
+ { |
+ href: "style.css?3", |
+ integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w==" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with empty integrity", |
+ { |
+ href: "style.css?4", |
+ integrity: "" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ false, |
+ "Same-origin with incorrect hash.", |
+ { |
+ href: "style.css?5", |
+ integrity: "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with multiple sha256 hashes, including correct.", |
+ { |
+ href: "style.css?6", |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with multiple sha256 hashes, including unknown algorithm.", |
+ { |
+ href: "style.css?7", |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with sha256 mismatch, sha512 match", |
+ { |
+ href: "style.css?8", |
+ integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ false, |
+ "Same-origin with sha256 match, sha512 mismatch", |
+ { |
+ href: "style.css?9", |
+ integrity: "sha512-deadbeef9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2== sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "<crossorigin='anonymous'> with correct hash, ACAO: *", |
+ { |
+ href: xorigin_anon_style + '&1', |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", |
+ crossorigin: "anonymous" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ false, |
+ "<crossorigin='anonymous'> with incorrect hash, ACAO: *", |
+ { |
+ href: xorigin_anon_style + '&2', |
+ integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=", |
+ crossorigin: "anonymous" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "<crossorigin='use-credentials'> with correct hash, CORS-eligible", |
+ { |
+ href: xorigin_creds_style + '&1', |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", |
+ crossorigin: "use-credentials" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ false, |
+ "<crossorigin='use-credentials'> with incorrect hash CORS-eligible", |
+ { |
+ href: xorigin_creds_style + '&2', |
+ integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=", |
+ crossorigin: "use-credentials" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ false, |
+ "<crossorigin='anonymous'> with CORS-ineligible resource", |
+ { |
+ href: xorigin_ineligible_style + '&1', |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", |
+ crossorigin: "anonymous" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ false, |
+ "Cross-origin, not CORS request, with correct hash", |
+ { |
+ href: xorigin_anon_style + '&3', |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ false, |
+ "Cross-origin, not CORS request, with hash mismatch", |
+ { |
+ href: xorigin_anon_style + '&4', |
+ integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Cross-origin, empty integrity", |
+ { |
+ href: xorigin_anon_style + '&5', |
+ integrity: "" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with correct hash, options.", |
+ { |
+ href: "style.css?10", |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with unknown algorithm only.", |
+ { |
+ href: "style.css?11", |
+ integrity: "foo666-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with correct sha256 hash, rel='stylesheet license'", |
+ { |
+ href: "style.css?12", |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", |
+ rel: "stylesheet license" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with correct sha256 hash, rel='license stylesheet'", |
+ { |
+ href: "style.css?13", |
+ integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", |
+ rel: "license stylesheet" |
+ } |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ true, |
+ "Same-origin with correct sha256 and sha512 hash, rel='alternate stylesheet' enabled", |
+ { |
+ href: "alternate.css?1", |
+ title: "alt", |
+ type: "text/css", |
+ class: "alternate", |
+ disabled: "disabled", |
+ rel: "alternate stylesheet", |
+ integrity: "sha256-phbz83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-8OYEB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==", |
+ }, |
+ function (link, container) { |
+ var alternate = document.querySelector('link.alternate'); |
+ alternate.disabled = false; |
+ }, |
+ "rgb(255, 0, 0)" |
+ ); |
+ |
+ new SRIStyleTest( |
+ style_tests, |
+ false, |
+ "Same-origin with incorrect sha256 and sha512 hash, rel='alternate stylesheet' enabled", |
+ { |
+ href: "alternate.css?2", |
+ title: "alt", |
+ type: "text/css", |
+ class: "alternate", |
+ disabled: "disabled", |
+ rel: "alternate stylesheet", |
+ integrity: "sha256-fail83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-failB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==", |
+ }, |
+ function (link, container) { |
+ var alternate = document.querySelector('link.alternate'); |
+ alternate.disabled = false; |
+ } |
+ ); |
+ |
+ style_tests.execute(); |
+ |
+</script> |
+<!-- TODO check cache-poisoned resources, transfer-encoding, 3xx redirect |
+ to resource with matching hash, and cross-origin leakage test as in sec5.3. |
+ --> |