过滤XSS攻击
安装
npm install xss
原理
通过标签白名单及属性白名单来过滤HTML标签,同时对包含特殊字符的属性值进行处理。默认配置可过滤大多数的XSS攻击代码,可根据实际应用场景来定制白名单及过滤方法。
使用方法
载入模块
var xss = require('xss');
使用默认的配置
var html = xss('<script>alert("xss");</script>');
console.log(html);
修改默认配置
// 添加或更新白名单中的标签 标签名(小写) = ['允许的属性列表(小写)']
xss.whiteList['p'] = ['class', 'style'];
// 删除默认的白名单标签
delete xss.whiteList['div'];
// 自定义处理属性值函数
xss.onTagAttr = function (tag, attr, vaule) {
// tag:当前标签名(小写)
// attr:当前属性名(小写)
// value:当前属性值
// 返回新的属性值,如果想使用默认的处理方式,不返回任何值即可
// 比如把属性值中的双引号替换为&quote;:return value.replace(/"/g, '&quote;');
// 以下为默认的处理代码:
if (attr === 'href' || attr === 'src') {
if (/\/\*|\*\//mg.test(value)) {
return '#';
}
if (/^[\s"'`]*((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/ig.test(value)) {
return '#';
}
} else if (attr === 'style') {
if (/\/\*|\*\//mg.test(value)) {
return '#';
}
if (/((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/ig.test(value)) {
return '';
}
}
};
// 自定义处理不在白名单中的标签
xss.onIgnoreTag = function (tag, html) {
// tag:当前标签名(小写),如:a
// html:当前标签的HTML代码,如:<a href="ooxx">
// 返回新的标签HTML代码,如果想使用默认的处理方式,不返回任何值即可
// 比如将标签替换为[removed]:return '[removed]';
// 以下为默认的处理代码:
return html.replace(/</g, '<').replace(/>/g, '>');
}
使用临时配置
var options = {
whiteList: {}, // 若不指定则使用默认配置,可参考xss.whiteList
onTagAttr: function () {}, // 若不指定则使用默认配置,可参考xss.onTagAttr
onIgnoreTag: function () {} // 若不指定则使用默认配置,可参考xss.onIgnoreTag
};
var html = xss('<script>alert("xss");</script>', options);
console.log(html);
测试
单元测试
在源码目录执行命令:npm test
在线测试
在源码目录执行命令:node cli.js,可在命令行中输入HTML代码,并看到过滤后的代码
性能
解析速度为5.81MB/s,而另外一个validator模块的xss()函数速度仅为2.48MB/s。
测试代码参考benchmark目录
项目地址:https://github.com/leizongmin/js-xss
希望此模块能完美解决XSS问题,我好将功补过 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@suqian](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian)](/user/suqian) [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@snoopy](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy)](/user/snoopy) [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@jiyinyiyong](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong)](/user/jiyinyiyong) [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@j4cnodejs](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs)](/user/j4cnodejs) [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@atian25](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25)](/user/atian25) [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@saighost](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)](/user/saighost)
@zxc122333 去看了一下, 那个网站已经说得很清楚了,& JavaScript includes (works in Netscape 4.x)
, 只对Netscape 4.x 浏览器有效. 注意它每条XSS下的Browser support [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02] **[NS4]**
, 灰色的不支持,粗黑的支持
@suqian @j4cnodejs saighost @snoopy 现在已能过滤XSS Cheet Sheet中的大部分"异常代码“,并且解析速度还算可以,为6.26MB/s,而另外一个validator模块的xss()函数速度仅为2.82MB/s。
XSS测试代码:https://github.com/leizongmin/js-xss/blob/master/test/test_xss.js
请各位大大检阅。
@leizongmin 不错,我测过了, 除了你明示未实现的, 大部分XSS都能过滤出来, 表扬一记!
根据我们CMS实际使用情况, 这些tag也请列入默认白名单:
em:['style'], cite:['style']
发现Bug了, xss()会把这样的代码:
<a href='/user/test'><img src='/user_data/avatar/avatar.png' title='test1' /></a>
变成
<a href='/user_data/avatar/avatar.png'><img src='/user_data/avatar/avatar.png' title='test1' /></a>
,
也就是说 a.href = img.src 了
你试试是不是这样?
刚试了一下,没有问题(更新一下github上的代码再试试):
<a href="/user/test"><img src="/user_data/avatar/avatar.png" title="test1"></a>
为了方便测试,写了个命令行工具:https://github.com/leizongmin/js-xss/blob/master/cli.js 你可以下载源码到本地,运行cli.js即可在窗口中输入HTML代码并看到过滤情况。
新增了一个用于处理这些标签的函数
xss.onIgnoreTag = function (tag, html) {
// tag:当前标签名(小写),如:a
// html:当前标签的HTML代码,如:<a href="ooxx">
// 返回新的标签HTML代码,如果想使用默认的处理方式,不返回任何值即可
// 比如将标签替换为[removed]:return '[removed]';
// 以下为默认的处理代码:
return html.replace(/</g, '<').replace(/>/g, '>');
}
比如要直接隐藏这些标签:
xss.onIgnoreTag = function (tag, html) {
return '';
};
详细使用方法看这里:https://github.com/leizongmin/js-xss
@leizongmin 这个我昨天试过了,挺好的!可它只能把标签隐藏掉,不能把标签的内容隐藏掉啊:
<script>alert('xss');</script>
=> script是去掉了,可是 alert(‘xss’);显示出来了
@j4cnodejs 这个有点麻烦,假如输入的内容是这样的:
<script>alert('xss');
<div><p>该干嘛干嘛去</p>
<img src="ooxx">
<script>
标签没有配对出现,那后面的其他标签都要隐藏么?