subresource-integrity.html (15359B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <title>Subresource Integrity</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="/resources/sriharness.js"></script> 7 <script src="/common/utils.js"></script> 8 <script src="sri-test-helpers.sub.js"></script> 9 10 <div id="log"></div> 11 12 <div id="container"></div> 13 <script> 14 var style_tests = []; 15 style_tests.execute = function() { 16 if (this.length > 0) { 17 this.shift().execute(); 18 } 19 } 20 add_result_callback(function(res) { 21 if (res.name.startsWith("Style: ")) { 22 style_tests.execute(); 23 } 24 }); 25 26 // Script tests 27 new SRIScriptTest( 28 true, 29 "Same-origin with correct sha256 hash.", 30 `${same_origin_prefix}script.js?${token()}`, 31 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=" 32 ).execute(); 33 34 new SRIScriptTest( 35 true, 36 "Same-origin with correct sha384 hash.", 37 `${same_origin_prefix}script.js?${token()}`, 38 "sha384-cINXh+nCzEHPWzXS7eoT+vYMBpyqczOybRLNU3XAButFWCRhHT5hLByIbPRqIm2f" 39 ).execute(); 40 41 new SRIScriptTest( 42 true, 43 "Same-origin with correct sha512 hash.", 44 `${same_origin_prefix}script.js?${token()}`, 45 "sha512-KZdenhzBd7X7Q/vmaOSyvFz1CGdoVt26xzCZjlkU9lfBEK+V/ougGys7iYDi0+tOHIQSQa87bIqx95R7GU7I9Q==" 46 ).execute(); 47 48 new SRIScriptTest( 49 true, 50 "Same-origin with empty integrity.", 51 `${same_origin_prefix}script.js?${token()}`, 52 "" 53 ).execute(); 54 55 new SRIScriptTest( 56 true, 57 "Same-origin with non-Base64 hash.", 58 `${same_origin_prefix}script.js?${token()}`, 59 "sha256-..." 60 ).execute(); 61 62 new SRIScriptTest( 63 false, 64 "Same-origin with incorrect hash.", 65 `${same_origin_prefix}script.js?${token()}`, 66 "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 67 ).execute(); 68 69 // Scripts with integrity attribute changed after #prepare-a-script. 70 new SRIScriptTest( 71 false, 72 "Same-origin with incorrect integrity => cleared after prepare.", 73 `${same_origin_prefix}script.js?${token()}`, 74 "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead", 75 undefined, 76 undefined, 77 null 78 ).execute(); 79 80 new SRIScriptTest( 81 false, 82 "Same-origin with incorrect integrity => set to correct hash after prepare.", 83 `${same_origin_prefix}script.js?${token()}`, 84 "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead", 85 undefined, 86 undefined, 87 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=" 88 ).execute(); 89 90 new SRIScriptTest( 91 true, 92 "Same-origin with empty integrity => set to incorrect hash after prepare.", 93 `${same_origin_prefix}script.js?${token()}`, 94 "", 95 undefined, 96 undefined, 97 "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 98 ).execute(); 99 100 new SRIScriptTest( 101 true, 102 "Same-origin with correct integrity => set to incorrect hash after prepare.", 103 `${same_origin_prefix}script.js?${token()}`, 104 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=", 105 undefined, 106 undefined, 107 "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 108 ).execute(); 109 110 new SRIScriptTest( 111 true, 112 "Same-origin with multiple sha256 hashes, including correct.", 113 `${same_origin_prefix}script.js?${token()}`, 114 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 115 ).execute(); 116 117 new SRIScriptTest( 118 true, 119 "Same-origin with multiple sha256 hashes, including unknown algorithm.", 120 `${same_origin_prefix}script.js?${token()}`, 121 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 122 ).execute(); 123 124 new SRIScriptTest( 125 true, 126 "Same-origin with sha256 mismatch, sha512 match", 127 `${same_origin_prefix}script.js?${token()}`, 128 "sha512-KZdenhzBd7X7Q/vmaOSyvFz1CGdoVt26xzCZjlkU9lfBEK+V/ougGys7iYDi0+tOHIQSQa87bIqx95R7GU7I9Q== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 129 ).execute(); 130 131 new SRIScriptTest( 132 false, 133 "Same-origin with sha256 match, sha512 mismatch", 134 `${same_origin_prefix}script.js?${token()}`, 135 "sha512-deadbeefspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=" 136 ).execute(); 137 138 new SRIScriptTest( 139 true, 140 "<crossorigin='anonymous'> with correct hash, ACAO: *", 141 `${xorigin_prefix}script.js?${token()}&pipe=header(Access-Control-Allow-Origin,*)`, 142 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=", 143 "anonymous" 144 ).execute(); 145 146 new SRIScriptTest( 147 false, 148 "<crossorigin='anonymous'> with incorrect hash, ACAO: *", 149 `${xorigin_prefix}script.js?${token()}&pipe=header(Access-Control-Allow-Origin,*)`, 150 "sha256-deadbeefcSLlbFZCj1OACLxTxVck2TOrBTEdUbwz1yU=", 151 "anonymous" 152 ).execute(); 153 154 new SRIScriptTest( 155 true, 156 "<crossorigin='use-credentials'> with correct hash, CORS-eligible", 157 `${xorigin_prefix}script.js?${token()}&pipe=header(Access-Control-Allow-Credentials,true)|header(Access-Control-Allow-Origin,${location.origin})`, 158 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=", 159 "use-credentials" 160 ).execute(); 161 162 new SRIScriptTest( 163 false, 164 "<crossorigin='use-credentials'> with incorrect hash CORS-eligible", 165 `${xorigin_prefix}script.js?${token()}&pipe=header(Access-Control-Allow-Credentials,true)|header(Access-Control-Allow-Origin,${location.origin})`, 166 "sha256-deadbeef2S+pTRZgiw3DWrhC6JLDlt2zRyGpwH7unU8=", 167 "use-credentials" 168 ).execute(); 169 170 new SRIScriptTest( 171 false, 172 "<crossorigin='anonymous'> with CORS-ineligible resource", 173 `${xorigin_prefix}script.js?${token()}`, /* no ACAO header makes this CORS-ineligible */ 174 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=", 175 "anonymous" 176 ).execute(); 177 178 new SRIScriptTest( 179 false, 180 "Cross-origin, not CORS request, with correct hash", 181 `${xorigin_prefix}script.js?${token()}&pipe=header(Access-Control-Allow-Origin,*)`, 182 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=" 183 ).execute(); 184 185 new SRIScriptTest( 186 false, 187 "Cross-origin, not CORS request, with hash mismatch", 188 `${xorigin_prefix}script.js?${token()}&pipe=header(Access-Control-Allow-Origin,*)`, 189 "sha256-deadbeef01Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=" 190 ).execute(); 191 192 new SRIScriptTest( 193 true, 194 "Cross-origin, empty integrity", 195 `${xorigin_prefix}script.js?${token()}&pipe=header(Access-Control-Allow-Origin,*)`, 196 "" 197 ).execute(); 198 199 new SRIScriptTest( 200 true, 201 "Same-origin with correct hash, options.", 202 `${same_origin_prefix}script.js?${token()}`, 203 "sha256-Bu681KMnQ15RYHFvsYdWumweeFAw0hJDTFt9seErghA=?foo=bar?spam=eggs" 204 ).execute(); 205 206 new SRIScriptTest( 207 true, 208 "Same-origin with unknown algorithm only.", 209 `${same_origin_prefix}script.js?${token()}`, 210 "foo666-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=" 211 ).execute(); 212 213 // Style tests 214 new SRIStyleTest( 215 style_tests, 216 true, 217 "Same-origin with correct sha256 hash", 218 { 219 href: "style.css?1", 220 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" 221 } 222 ); 223 224 new SRIStyleTest( 225 style_tests, 226 true, 227 "Same-origin with correct sha384 hash", 228 { 229 href: "style.css?2", 230 integrity: "sha384-wDAWxH4tOWBwAwHfBn9B7XuNmFxHTMeigAMwn0iVQ0zq3FtmYMLxihcGnU64CwcX" 231 } 232 ); 233 234 new SRIStyleTest( 235 style_tests, 236 true, 237 "Same-origin with correct sha512 hash", 238 { 239 href: "style.css?3", 240 integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w==" 241 } 242 ); 243 244 new SRIStyleTest( 245 style_tests, 246 true, 247 "Same-origin with empty integrity", 248 { 249 href: "style.css?4", 250 integrity: "" 251 } 252 ); 253 254 new SRIStyleTest( 255 style_tests, 256 true, 257 "Same-origin with non-Base64 integrity", 258 { 259 href: "style.css?4.5", 260 integrity: "sha256-..." 261 } 262 ); 263 264 new SRIStyleTest( 265 style_tests, 266 false, 267 "Same-origin with incorrect hash.", 268 { 269 href: "style.css?5", 270 integrity: "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 271 } 272 ); 273 274 new SRIStyleTest( 275 style_tests, 276 true, 277 "Same-origin with multiple sha256 hashes, including correct.", 278 { 279 href: "style.css?6", 280 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 281 } 282 ); 283 284 new SRIStyleTest( 285 style_tests, 286 true, 287 "Same-origin with multiple sha256 hashes, including unknown algorithm.", 288 { 289 href: "style.css?7", 290 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 291 } 292 ); 293 294 new SRIStyleTest( 295 style_tests, 296 true, 297 "Same-origin with sha256 mismatch, sha512 match", 298 { 299 href: "style.css?8", 300 integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" 301 } 302 ); 303 304 new SRIStyleTest( 305 style_tests, 306 false, 307 "Same-origin with sha256 match, sha512 mismatch", 308 { 309 href: "style.css?9", 310 integrity: "sha512-deadbeef9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2== sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" 311 } 312 ); 313 314 new SRIStyleTest( 315 style_tests, 316 true, 317 "<crossorigin='anonymous'> with correct hash, ACAO: *", 318 { 319 href: xorigin_anon_style + '&1', 320 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", 321 crossorigin: "anonymous" 322 } 323 ); 324 325 new SRIStyleTest( 326 style_tests, 327 false, 328 "<crossorigin='anonymous'> with incorrect hash, ACAO: *", 329 { 330 href: xorigin_anon_style + '&2', 331 integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=", 332 crossorigin: "anonymous" 333 } 334 ); 335 336 new SRIStyleTest( 337 style_tests, 338 true, 339 "<crossorigin='use-credentials'> with correct hash, CORS-eligible", 340 { 341 href: xorigin_creds_style + '&1', 342 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", 343 crossorigin: "use-credentials" 344 } 345 ); 346 347 new SRIStyleTest( 348 style_tests, 349 false, 350 "<crossorigin='use-credentials'> with incorrect hash CORS-eligible", 351 { 352 href: xorigin_creds_style + '&2', 353 integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=", 354 crossorigin: "use-credentials" 355 } 356 ); 357 358 new SRIStyleTest( 359 style_tests, 360 false, 361 "<crossorigin='anonymous'> with CORS-ineligible resource", 362 { 363 href: xorigin_ineligible_style + '&1', 364 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", 365 crossorigin: "anonymous" 366 } 367 ); 368 369 new SRIStyleTest( 370 style_tests, 371 false, 372 "Cross-origin, not CORS request, with correct hash", 373 { 374 href: xorigin_anon_style + '&3', 375 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=" 376 } 377 ); 378 379 new SRIStyleTest( 380 style_tests, 381 false, 382 "Cross-origin, not CORS request, with hash mismatch", 383 { 384 href: xorigin_anon_style + '&4', 385 integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=" 386 } 387 ); 388 389 new SRIStyleTest( 390 style_tests, 391 true, 392 "Cross-origin, empty integrity", 393 { 394 href: xorigin_anon_style + '&5', 395 integrity: "" 396 } 397 ); 398 399 new SRIStyleTest( 400 style_tests, 401 true, 402 "Same-origin with correct hash, options.", 403 { 404 href: "style.css?10", 405 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs" 406 } 407 ); 408 409 new SRIStyleTest( 410 style_tests, 411 true, 412 "Same-origin with unknown algorithm only.", 413 { 414 href: "style.css?11", 415 integrity: "foo666-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs" 416 } 417 ); 418 419 new SRIStyleTest( 420 style_tests, 421 true, 422 "Same-origin with correct sha256 hash, rel='stylesheet license'", 423 { 424 href: "style.css?12", 425 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", 426 rel: "stylesheet license" 427 } 428 ); 429 430 new SRIStyleTest( 431 style_tests, 432 true, 433 "Same-origin with correct sha256 hash, rel='license stylesheet'", 434 { 435 href: "style.css?13", 436 integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=", 437 rel: "license stylesheet" 438 } 439 ); 440 441 new SRIStyleTest( 442 style_tests, 443 true, 444 "Same-origin with correct sha256 and sha512 hash, rel='alternate stylesheet' enabled", 445 { 446 href: "alternate.css?1", 447 title: "alt", 448 type: "text/css", 449 class: "alternate", 450 disabled: "disabled", 451 rel: "alternate stylesheet", 452 integrity: "sha256-phbz83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-8OYEB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==", 453 }, 454 function (link, container) { 455 var alternate = document.querySelector('link.alternate'); 456 alternate.disabled = false; 457 }, 458 "rgb(255, 0, 0)" 459 ); 460 461 new SRIStyleTest( 462 style_tests, 463 false, 464 "Same-origin with incorrect sha256 and sha512 hash, rel='alternate stylesheet' enabled", 465 { 466 href: "alternate.css?2", 467 title: "alt", 468 type: "text/css", 469 class: "alternate", 470 disabled: "disabled", 471 rel: "alternate stylesheet", 472 integrity: "sha256-fail83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-failB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==", 473 }, 474 function (link, container) { 475 var alternate = document.querySelector('link.alternate'); 476 alternate.disabled = false; 477 } 478 ); 479 480 style_tests.execute(); 481 482 </script> 483 <!-- TODO check cache-poisoned resources, transfer-encoding, 3xx redirect 484 to resource with matching hash, and cross-origin leakage test as in sec5.3. 485 -->