2012-09-18 23:23:16 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 测试XSS
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
var assert = require('assert');
|
|
|
|
|
|
var xss = require('../');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('test XSS', function () {
|
|
|
|
|
|
|
|
|
|
|
|
it('#normal', function () {
|
|
|
|
|
|
|
|
|
|
|
|
// 过滤不在白名单的标签
|
|
|
|
|
|
assert.equal(xss('<b>abcd</b>'), '<b>abcd</b>');
|
|
|
|
|
|
assert.equal(xss('<o>abcd</o>'), '<o>abcd</o>');
|
|
|
|
|
|
assert.equal(xss('<b>abcd</o>'), '<b>abcd</o>');
|
|
|
|
|
|
assert.equal(xss('<b><o>abcd</b></o>'), '<b><o>abcd</b></o>');
|
|
|
|
|
|
assert.equal(xss('<hr>'), '<hr>');
|
|
|
|
|
|
assert.equal(xss('<xss>'), '<xss>');
|
|
|
|
|
|
assert.equal(xss('<xss o="x">'), '<xss o="x">');
|
|
|
|
|
|
assert.equal(xss('<a><b>c</b></a>'), '<a><b>c</b></a>');
|
|
|
|
|
|
assert.equal(xss('<a><c>b</c></a>'), '<a><c>b</c></a>');
|
|
|
|
|
|
|
|
|
|
|
|
// 过滤不是标签的<>
|
|
|
|
|
|
assert.equal(xss('<>>'), '<>>');
|
|
|
|
|
|
assert.equal(xss('<script>'), '<script>');
|
|
|
|
|
|
assert.equal(xss('<<a>b>'), '<<a>b>');
|
|
|
|
|
|
assert.equal(xss('<<<a>>b</a><x>'), '<<<a>>b</a><x>');
|
|
|
|
|
|
|
2013-11-05 15:40:17 +08:00
|
|
|
|
// 过滤不在白名单中的属性
|
2012-09-18 23:23:16 +08:00
|
|
|
|
assert.equal(xss('<a oo="1" xx="2" href="3">yy</a>'), '<a href="3">yy</a>');
|
|
|
|
|
|
assert.equal(xss('<a href xx oo>pp</a>'), '<a href>pp</a>');
|
|
|
|
|
|
assert.equal(xss('<a href "">pp</a>'), '<a href>pp</a>');
|
|
|
|
|
|
assert.equal(xss('<a t="">'), '<a>');
|
|
|
|
|
|
|
|
|
|
|
|
// 属性内的特殊字符
|
|
|
|
|
|
assert.equal(xss('<a href="\'<<>>">'), '<a href="\'<<>>">');
|
2012-09-19 08:20:38 +08:00
|
|
|
|
assert.equal(xss('<a href=""">'), '<a href=\"\"\">');
|
2012-09-19 09:04:23 +08:00
|
|
|
|
assert.equal(xss('<a h=href="oo">'), '<a>');
|
|
|
|
|
|
assert.equal(xss('<a h= href="oo">'), '<a href="oo">');
|
2012-09-19 08:20:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 自动将属性值的单引号转为双引号
|
|
|
|
|
|
assert.equal(xss('<a href=\'abcd\'>'), '<a href="abcd">');
|
|
|
|
|
|
assert.equal(xss('<a href=\'"\'>'), '<a href=""e;">');
|
|
|
|
|
|
|
2012-09-19 09:04:23 +08:00
|
|
|
|
// 没有双引号括起来的属性值
|
|
|
|
|
|
assert.equal(xss('<a href=home>'), '<a href="home">');
|
2012-09-19 09:54:07 +08:00
|
|
|
|
assert.equal(xss('<a href=abc("d")>'), '<a href="abc("e;d"e;)">');
|
|
|
|
|
|
assert.equal(xss('<a href=abc(\'d\')>'), '<a href="abc(\'d\')">');
|
2012-09-19 09:04:23 +08:00
|
|
|
|
|
2012-09-20 20:30:32 +08:00
|
|
|
|
// 单个闭合标签
|
|
|
|
|
|
assert.equal(xss('<img src="#"/>'), '<img src="#" />');
|
|
|
|
|
|
assert.equal(xss('<img src="#" />'), '<img src="#" />');
|
|
|
|
|
|
assert.equal(xss('<img src="#"//>'), '<img src="#">');
|
2013-11-05 15:40:17 +08:00
|
|
|
|
assert.equal(xss('<br/>'), '<br />');
|
|
|
|
|
|
assert.equal(xss('<br />'), '<br />');
|
2012-09-20 20:30:32 +08:00
|
|
|
|
|
2012-09-18 23:23:16 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2012-09-19 19:56:20 +08:00
|
|
|
|
// 自定义白名单
|
2012-09-18 23:23:16 +08:00
|
|
|
|
it('#white list', function () {
|
|
|
|
|
|
|
|
|
|
|
|
// 过滤所有标签
|
2012-09-19 19:56:20 +08:00
|
|
|
|
assert.equal(xss('<a href="xx">bb</a>', {whiteList: {}}), '<a href="xx">bb</a>');
|
|
|
|
|
|
assert.equal(xss('<hr>', {whiteList: {}}), '<hr>');
|
2012-09-18 23:23:16 +08:00
|
|
|
|
// 增加白名单标签及属性
|
2012-09-19 19:56:20 +08:00
|
|
|
|
assert.equal(xss('<ooxx yy="ok" cc="no">uu</ooxx>', {whiteList: {ooxx: ['yy']}}), '<ooxx yy="ok">uu</ooxx>');
|
2012-09-18 23:23:16 +08:00
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2012-09-19 19:56:20 +08:00
|
|
|
|
// 自定义过滤属性函数
|
2012-09-19 08:00:01 +08:00
|
|
|
|
it('#process attribute value', function () {
|
|
|
|
|
|
|
2012-09-19 19:56:20 +08:00
|
|
|
|
assert.equal(xss('<a href="ignore:ooxx">abc</a><a href="ooxx">', {
|
|
|
|
|
|
onTagAttr: function (tag, attr, value) {
|
|
|
|
|
|
if (tag === 'a' && attr === 'href') {
|
|
|
|
|
|
if (value.substr(0, 7) === 'ignore:') {
|
|
|
|
|
|
return '#';
|
|
|
|
|
|
}
|
2012-09-19 08:00:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2012-09-19 19:56:20 +08:00
|
|
|
|
}), '<a href="#">abc</a><a href="ooxx">');
|
2012-09-19 08:00:01 +08:00
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2012-09-19 19:56:20 +08:00
|
|
|
|
// 自定义处理不在白名单中的标签
|
|
|
|
|
|
it('#process ignore tag', function () {
|
|
|
|
|
|
|
2012-09-20 20:30:32 +08:00
|
|
|
|
// 过滤标签
|
2012-09-19 19:56:20 +08:00
|
|
|
|
assert.equal(xss('<ooxx xxyy>ookk</ooxx><img>', {
|
|
|
|
|
|
onIgnoreTag: function (tag, html) {
|
|
|
|
|
|
return '';
|
|
|
|
|
|
}
|
|
|
|
|
|
}), 'ookk<img>');
|
|
|
|
|
|
assert.equal(xss('<ooxx xxyy>ookk</ooxx><img>', {
|
|
|
|
|
|
onIgnoreTag: function (tag, html) {
|
|
|
|
|
|
return '[removed]';
|
|
|
|
|
|
}
|
|
|
|
|
|
}), '[removed]ookk[removed]<img>');
|
|
|
|
|
|
|
2012-09-20 20:30:32 +08:00
|
|
|
|
// 检验附加属性
|
|
|
|
|
|
var isClosing = [];
|
|
|
|
|
|
var position = [];
|
|
|
|
|
|
var originalPosition = [];
|
|
|
|
|
|
var html = xss('TTG:<ooxx href="ooy" >ds</ooxx>--ds d<yy hh uu>', {
|
|
|
|
|
|
onIgnoreTag: function (tag, html, options) {
|
|
|
|
|
|
isClosing.push(options.isClosing);
|
|
|
|
|
|
position.push(options.position);
|
|
|
|
|
|
originalPosition.push(options.originalPosition);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
//console.log(html);
|
|
|
|
|
|
assert.deepEqual(isClosing, [false, true, false]);
|
|
|
|
|
|
assert.deepEqual(position, [4, 30, 50]);
|
|
|
|
|
|
assert.deepEqual(originalPosition, [4, 24, 38]);
|
|
|
|
|
|
|
2012-09-20 20:55:42 +08:00
|
|
|
|
// 替换检验 utils.tagFilter()
|
|
|
|
|
|
var filter = xss.utils.tagFilter(['script']);
|
2012-09-20 20:30:32 +08:00
|
|
|
|
var html = xss('<b >script is <script t="d">alert("xss"); ooxx()</script>, wahaha!!</b>', {
|
2012-09-20 20:55:42 +08:00
|
|
|
|
onIgnoreTag: filter.onIgnoreTag
|
2012-09-20 20:30:32 +08:00
|
|
|
|
});
|
2012-09-20 20:55:42 +08:00
|
|
|
|
assert.equal(filter.filter(html), '<b>script is , wahaha!!</b>');
|
|
|
|
|
|
|
|
|
|
|
|
var filter = xss.utils.tagFilter(['x2']);
|
|
|
|
|
|
var html = xss('<x1></b><x2>dds</x2><x3>fd</x3>', {
|
|
|
|
|
|
onIgnoreTag: filter.onIgnoreTag
|
2012-09-20 20:30:32 +08:00
|
|
|
|
});
|
2012-09-20 20:55:42 +08:00
|
|
|
|
assert.equal(filter.filter(html), '<x1></b><x3>fd</x3>');
|
2012-09-20 20:30:32 +08:00
|
|
|
|
|
2012-09-19 19:56:20 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-09-19 09:04:23 +08:00
|
|
|
|
// XSS攻击测试:https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
|
|
|
|
|
|
it('#XSS_Filter_Evasion_Cheat_Sheet', function () {
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('></SCRIPT>">\'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>'),
|
|
|
|
|
|
'></SCRIPT>">\'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss(';!--"<XSS>=&{()}'), ';!--"<XSS>=&{()}');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>'),
|
|
|
|
|
|
'<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC="javascript:alert(\'XSS\');">'), '<img src="#">');
|
|
|
|
|
|
|
2012-09-19 09:54:07 +08:00
|
|
|
|
assert.equal(xss('<IMG SRC=javascript:alert(\'XSS\')>'), '<img src="#">');
|
2012-09-19 09:04:23 +08:00
|
|
|
|
|
2012-09-19 10:12:10 +08:00
|
|
|
|
assert.equal(xss('<IMG SRC=JaVaScRiPt:alert(\'XSS\')>'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC=`javascript:alert("RSnake says, \'XSS\'")`>'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG """><SCRIPT>alert("XSS")</SCRIPT>">'), '<img>');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC=javascript:alert('XSS')>'),
|
|
|
|
|
|
'<img src="#">');
|
|
|
|
|
|
|
2013-12-24 12:10:18 +08:00
|
|
|
|
assert.equal(xss('<IMG SRC=javascript:alert('XSS')>'),
|
|
|
|
|
|
'<img src="#">');
|
2012-09-19 10:27:24 +08:00
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC=javascript:alert('XSS')>'),
|
2013-12-24 12:06:52 +08:00
|
|
|
|
'<img src="#">');
|
2012-09-19 10:27:24 +08:00
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC="jav ascript:alert(\'XSS\');">'), '<img src="#">');
|
|
|
|
|
|
|
2012-09-19 10:44:26 +08:00
|
|
|
|
assert.equal(xss('<IMG SRC="jav	ascript:alert(\'XSS\');">'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC="jav\nascript:alert(\'XSS\');">'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC=java\0script:alert(\"XSS\")>'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC="  javascript:alert(\'XSS\');">'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>'),
|
|
|
|
|
|
'<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>'),
|
|
|
|
|
|
'<BODY onload!#$%&()*~+-_.,:;?@[/|]^`=alert(\"XSS\")>');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<<SCRIPT>alert("XSS");//<</SCRIPT>'),
|
|
|
|
|
|
'<<SCRIPT>alert(\"XSS\");//<</SCRIPT>');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >'),
|
|
|
|
|
|
'<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<SCRIPT SRC=//ha.ckers.org/.j'),
|
|
|
|
|
|
'<SCRIPT SRC=//ha.ckers.org/.j');
|
|
|
|
|
|
|
2012-09-19 11:10:16 +08:00
|
|
|
|
assert.equal(xss('<IMG SRC="javascript:alert(\'XSS\')"'),
|
|
|
|
|
|
'<IMG SRC=\"javascript:alert(\'XSS\')"');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<iframe src=http://ha.ckers.org/scriptlet.html <'),
|
|
|
|
|
|
'<iframe src=http://ha.ckers.org/scriptlet.html <');
|
|
|
|
|
|
|
2013-05-27 10:54:02 +08:00
|
|
|
|
assert.equal(xss('<a style="url(\'javascript:alert(1)\')">', {whiteList: {a: ['style']}}), '<a style>');
|
2012-09-19 11:10:16 +08:00
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC=\'vbscript:msgbox("XSS")\'>'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC="livescript:[code]">'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<IMG SRC="mocha:[code]">'), '<img src="#">');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<a href="javas/**/cript:alert(\'XSS\');">'), '<a href="#">');
|
|
|
|
|
|
|
|
|
|
|
|
// 这个暂时不知道怎么处理
|
|
|
|
|
|
//assert.equal(xss('¼script¾alert(¢XSS¢)¼/script¾'), '');
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(xss('<!--[if gte IE 4]><SCRIPT>alert(\'XSS\');</SCRIPT><![endif]-->'),
|
|
|
|
|
|
'<!--[if gte IE 4]><SCRIPT>alert(\'XSS\');</SCRIPT><![endif]-->');
|
|
|
|
|
|
|
2013-12-24 12:23:47 +08:00
|
|
|
|
// HTML5新增实体编码 冒号: 换行

|
|
|
|
|
|
assert.equal(xss('<a href="javascript:alert(/xss/)">'), '<a href="#">');
|
|
|
|
|
|
assert.equal(xss('<a href="javascript&colonalert(/xss/)">'), '<a href="#">');
|
|
|
|
|
|
assert.equal(xss('<a href="a
b">'), '<a href="a b">');
|
|
|
|
|
|
assert.equal(xss('<a href="a&NewLineb">'), '<a href="a b">');
|
2013-12-24 12:43:12 +08:00
|
|
|
|
assert.equal(xss('<a href="javasc
ript:alert(1)">'), '<a href="#">');
|
2012-09-19 09:04:23 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2012-09-18 23:23:16 +08:00
|
|
|
|
});
|