mirror of
https://github.com/servo/servo.git
synced 2025-07-12 18:03:49 +01:00
478 lines
14 KiB
HTML
478 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset=utf-8>
|
|
<title>Subresource Integrity</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/resources/sriharness.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';
|
|
|
|
// 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?';
|
|
|
|
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.
|
|
-->
|