-
Notifications
You must be signed in to change notification settings - Fork 13
/
xss.test.js
167 lines (130 loc) · 5.53 KB
/
xss.test.js
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
var counter = 0;
describe('XSS Attack Vectors', function() {
// Modified XSS String
// (Source: https://developers.google.com/closure/templates/docs/security#example)
var xss = "javascript:/*</style></script>/**/ /<script>1/(assert(false))//</script>";
afterEach(function() {
counter++;
});
it('should prevent injection to element innerHTML', function() {
var el = html`<p>${xss}</p>`;
document.body.appendChild(el);
});
it('should prevent injection to non-quoted element attributes', function() {
var el = html`<div data-xss=${xss}></div>`;
document.body.appendChild(el);
});
it('should prevent injection to single quoted element attributes', function() {
var el = html`<div data-xss='${xss}'></div>`;
document.body.appendChild(el);
});
it('should prevent injection to double quoted element attributes', function() {
var el = html`<div data-xss="${xss}"></div>`;
document.body.appendChild(el);
});
it('should prevent injection as a javascript quoted string', function() {
var el = html`<script>alert('${xss}')</script>`;
document.body.appendChild(el);
});
it('should prevent injection on one side of a javascript quoted expression', function() {
var el = html`<script>x='${xss}'</script>`;
document.body.appendChild(el);
});
it('should prevent injection into inlined quoted event handler', function() {
var el = html`<a href='#' onclick="x='${xss}'">XSS <p> tag</a>`;
document.body.appendChild(el);
el.click();
});
it('should prevent injection into quoted event handler', function() {
var el = html`<a href='#' onclick="${xss}">XSS <p> tag</a>`;
document.body.appendChild(el);
el.click();
});
it('should prevent injection into CSS unquote property', function() {
var el = html`<style>html { background: ${xss}; }</style>`;
document.body.appendChild(el);
});
it('should prevent injection into CSS quoted property', function() {
var el = html`<style>html { background: "${xss}"; }</style>`;
document.body.appendChild(el);
});
it('should prevent injection into CSS property of HTML style attribute', function() {
var el = html`<div style="background: ${xss}"></div>`;
document.body.appendChild(el);
});
it('should prevent injection into query params of HTML urls', function() {
var el = html`<p><a target='_blank' href="http://www.google.com?test=${xss}">XSS'ed Link</a></p>`;
document.body.appendChild(el);
el.click();
});
it('should prevent injection into HREF attribute of <a> tag', function() {
var el = html`<a href="${xss}">XSS'ed Link</a>`;
document.body.appendChild(el);
el.click();
});
it('should prevent against clobbering of /attributes/', function() {
var el = html`<form id="f" action="${xss}" onsubmit="return false;">
<input type="radio" name="attributes"//>
<input type="submit" />
</form>`;
document.body.appendChild(el);
// el.submit() does not trigger a submit event, so we need to click the submit button
// @see http://stackoverflow.com/questions/11557994/jquery-submit-vs-javascript-submit
el.querySelector('input[type="submit"]').click();
});
it('should prevent injection out of a tag name by throwing an error', function() {
var func = function() {
var el = html`<h${xss}></h${xss}>`;
document.body.appendChild(el);
};
expect(func).to.throw;
});
it('should prevent xss protocol URLs by rejecting them', function() {
var el = html`<a href="${xss}"></a>`;
document.body.appendChild(el);
el.click();
expect(el.getAttribute('href')[0]).to.equal('#');
});
it('should not prevent javascript protocol if it was a safe string', function() {
var value = 'foo/bar&baz/boo';
var el = html`<a href="javascript:void(0);">`;
expect(el.getAttribute('href')).to.equal('javascript:void(0);');
});
it('should prevent injection into uri custom attributes', function() {
var el = html`<a href="#" data-uri="${xss}">`
document.body.appendChild(el);
el.href = el.getAttribute('data-uri');
el.click();
});
it('should entity escape URLs', function() {
var value = 'foo/bar&baz/boo';
var el = html`<a href="${value}">`;
expect(el.getAttribute('href')).to.equal('foo/bar&baz/boo');
});
it('should percent encode inside URL query', function() {
var value = 'bar&baz=boo';
var el = html`<a href="foo?q=${value}">`;
expect(el.getAttribute('href')).to.equal('foo?q=bar%26baz%3Dboo');
});
it('should percent encode inside URL query and entity escape if not', function() {
var value = 'bar&baz=boo';
var el = html`<a href="foo/${value}/bar?q=${value}">`;
expect(el.getAttribute('href')).to.equal('foo/bar&baz=boo/bar?q=bar%26baz%3Dboo');
});
it('should reject a URL outright if it has the wrong protocol', function() {
var protocol = 'javascript:alert(1337)';
var value = '/foo&bar/bar';
var el = html`<a href="${protocol}/bar${value}">`;
expect(el.getAttribute('href')[0]).to.equal('#');
expect(el.getAttribute('href').indexOf('/bar')).to.equal(-1);
});
it('should allow a URL if it has a safe protocol', function() {
var protocol = 'http://localhost:500';
var value = '/foo?id=true';
var el = html`<a href="${protocol}/bar${value}">`;
expect(el.getAttribute('href')).to.equal('http://localhost:500/bar/foo?id=true');
var protocol = 'https://localhost:500';
var el = html`<a href="${protocol}/bar${value}">`;
expect(el.getAttribute('href')).to.equal('https://localhost:500/bar/foo?id=true');
});
});