-
Notifications
You must be signed in to change notification settings - Fork 0
/
integrity.html
151 lines (149 loc) · 6.15 KB
/
integrity.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>Demo Page for Integrity attribute</title>
<meta name=description content="demo page for integrity attribute in resources">
<meta http-equiv=X-UA-Compatible content="IE=Edge">
<meta name=viewport content="width=device-width,initial-scale=1.0">
<meta name=robots content=index,follow>
<link rel=canonical href=https://laysent.github.io/subresource-integrity-demo/integrity.html />
<link
href=./main.css
rel=stylesheet
integrity="sha512-mbzzgGIjfEC93ZP2SML7m8+qpNxg4KQH5s28RcwDGfgB8mpa9MbIlSg1GDd6IMeHowT1owpRqNnSJK7Feob12g=="
crossorigin=anonymous
/>
<link
href=https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/themes/prism.css
rel=stylesheet
integrity="sha256-/Kfdz9pXGPe+bFF+TtxHqbg6F9c3Rb0jN48uy+2b/do="
crossorigin=anonymous
/>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-31656866-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-31656866-1');
</script>
</head>
<body>
<main>
<h1>Integrity</h1>
<section>
<h2>explaination</h2>
<p>This demo page is to help you understand <em>integrity</em> attribute.</p>
<p>
You should be able to use querystring to control whether <em>integrity</em> is correct.
</p>
<ul>
<li><em>wrong-integrity=all</em> to set integrity incorrectly for all resources</li>
<li><em>wrong-integrity=script</em> to set integrity incorrectly for script</li>
<li><em>wrong-integrity=style</em> to set integrity incorrectly for style</li>
<li><em>wrong-integrity=invalid</em> to set invalid integrity</li>
</ul>
<p>
Available hash algorithms are <em>sha256</em>, <em>sha384</em> and <em>sha512</em>. One or
more hashes can be used as <em>integrity</em> attribute. The hash should have one of
<em>sha256-</em>, <em>sha384-</em> or <em>sha512-</em> at front and should be joined by
white space.
</p>
<p>
When multiple hash results are provided, the strongest hash result will be used. If multiple
hash results exists with same hash algorithm, the resource will be considered as valid if
any of the hashes matches the actual one. More examples regarding multiple hashes in
<em>integrity</em> can be found in <a href=./integrity-with-multiple-hashes.html>this demo</a>.
</p>
<p>
Following is the <em>Node.js</em> code you can use to generate hash for given content.
</p>
<p>
<pre><code class="language-javascript">require('crypto')
.createHash(type) // 'sha256', 'sha384' or 'sha512'
.update(content, 'utf8')
.digest('base64');
</code></pre>
</p>
</section>
<section>
<h2>Status of resources loading</h2>
<ul id=status-bar>
<li id=style-failed class=failed>Style failed to load</li>
<li id=style-succeeded class=succeeded>Style loaded successfully</li>
<li id=script-failed class=failed>Script failed to load</li>
</ul>
</section>
<section>
<h2>Crossorigin</h2>
<p>
When using <em>SRI</em>, it is usually necessary to include <em>crossorigin="anonymous"</em>
as well. The reason behind this is, <em>SRI</em> is designed to validate resources on
third-party CDN, where security is out of our hand. That means, the request is cross-domain.
To ensure the browser can read the content and calculate hash, <em>crossorigin="anonymous"</em>
is required and CDN must explicitly allow this. Otherwise the load of content will fail.
</p>
<p>
For resources within same domain, <em>crossorign="anonymous"</em> isn't required. However,
<em>SRI</em> does not play a key role in such scenario as well.
</p>
</section>
<section>
<a href=./index.html>Back</a>
</section>
<footer>
© 2018 LaySent.
</footer>
</main>
<script>
var querystring = location.search.substr(1).split('&').reduce((acc, pair) => {
var parts = pair.split('=');
acc[parts[0]] = parts[1];
return acc;
}, { });
var wrongIntegrity = querystring['wrong-integrity'];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = './style.css';
if (wrongIntegrity === 'all' || wrongIntegrity === 'style') {
link.integrity = 'sha256-wrong';
} else if (wrongIntegrity === 'invalid') {
link.integrity = 'invalid';
} else {
link.integrity = 'sha512-7z8mwAKsLTdd/Gto8TfFUpcx1F0+HMB2mxZpkthvOs7FAtKzVQiwa7fF48jSv2tk6vYRtgfT3K5l2DOMWrqyRA==';
}
link.onerror = () => {
console.error('failed to load stylesheet');
};
document.head.appendChild(link);
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = './script.js';
script.crossOrigin = 'anonymous';
if (wrongIntegrity === 'all' || wrongIntegrity === 'script') {
script.integrity = 'sha256-wrong';
} else if (wrongIntegrity === 'invalid') {
script.integrity = 'invalid';
} else {
script.integrity = 'sha512-zw36VuUy/09iVs2cRYeF80XlEEf0sRRDpBojNYf+3AlG++nhf6UcgWIQXiHKaLkw36VZLqV7nn/OeacCLsjaBA==';
}
script.onerror = () => {
console.error('failed to load script');
};
document.body.appendChild(script);
</script>
<script
type=text/javascript
src=https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/prism.min.js
integrity="sha256-jc6y1s/Y+F+78EgCT/lI2lyU7ys+PFYrRSJ6q8/R8+o="
crossorigin=anonymous
></script>
<script
type=text/javascript
src=https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/components/prism-javascript.min.js
integrity="sha256-G5C8j/0gBEHgf/x60UZQY5QrKPWdUo2Pgcu4OgU5q7w="
crossorigin=anonymous
></script>
</body>
</html>