-
Notifications
You must be signed in to change notification settings - Fork 83
/
xss.test.js
75 lines (69 loc) · 1.42 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
'use strict'
const { DOMParser } = require('../lib/dom-parser')
const excludeTags = new RegExp(
'^(?:' +
[
'javascript',
'vbscript',
'expression',
'meta',
'xml',
'blink',
'link',
'script',
'applet',
'embed',
'object',
'iframe',
'frame',
'frameset',
'ilayer',
'layer',
'bgsound',
'base',
].join('|') +
')$',
'i'
)
const excludeAttrs = /^on|style/i
const urlAttrs = /(?:href|src)/i
const invalidURL = /^(data|javascript|vbscript|ftp)\:/
function xss(html) {
const dom = new DOMParser({
xmlns: { '': 'http://www.w3.org/1999/xhtml' },
}).parseFromString(html, 'text/html')
return dom.documentElement.toString(true, function (node) {
switch (node.nodeType) {
case 1: //element
const tagName = node.tagName
if (excludeTags.test(tagName)) {
return ''
}
return node
case 2:
const attrName = node.name
if (excludeAttrs.test(attrName)) {
return null
}
if (urlAttrs.test(attrName)) {
const value = node.value
if (invalidURL.test(value)) {
return null
}
}
return node
case 3:
return node
}
})
}
describe('xss test', () => {
it('documentElement.toString(true, callback)', () => {
const html =
'<div onclick="alert(123)" title="32323"><script>alert(123)</script></div>'
const actual = xss(html)
expect(actual).toBe(
'<div title="32323" xmlns="http://www.w3.org/1999/xhtml"></div>'
)
})
})