默认href和src属性只运行 https, http, / 开头的地址
This commit is contained in:
@@ -117,25 +117,11 @@ function safeAttrValue (tag, name, value) {
|
||||
|
||||
if (name === 'href' || name === 'src') {
|
||||
// 过滤 href 和 src 属性
|
||||
// javascript:
|
||||
REGEXP_DEFAULT_ON_TAG_ATTR_1.lastIndex = 0;
|
||||
if (REGEXP_DEFAULT_ON_TAG_ATTR_1.test(value)) {
|
||||
// 仅允许 http:// | https:// | / 开头的地址
|
||||
value = value.trim();
|
||||
if (value && !REGEXP_DEFAULT_ON_TAG_ATTR_1.test(value)) {
|
||||
return '#';
|
||||
}
|
||||
// /*注释*/
|
||||
REGEXP_DEFAULT_ON_TAG_ATTR_2.lastIndex = 0;
|
||||
if (REGEXP_DEFAULT_ON_TAG_ATTR_2.test(value)) {
|
||||
return '#';
|
||||
}
|
||||
// data:
|
||||
REGEXP_DEFAULT_ON_TAG_ATTR_5.lastIndex = 0;
|
||||
if (REGEXP_DEFAULT_ON_TAG_ATTR_5.test(value)) {
|
||||
// 允许 data: image/* 类型
|
||||
REGEXP_DEFAULT_ON_TAG_ATTR_6.lastIndex = 0;
|
||||
if (!REGEXP_DEFAULT_ON_TAG_ATTR_6.test(value)) {
|
||||
return '#';
|
||||
}
|
||||
}
|
||||
} else if (name === 'style') {
|
||||
// 过滤 style 属性 (这个xss漏洞较老了,可能已经不适用)
|
||||
// javascript:
|
||||
@@ -163,8 +149,7 @@ var REGEXP_QUOTE_2 = /"/g;
|
||||
var REGEXP_ATTR_VALUE_1 = /&#([a-zA-Z0-9]*);?/img;
|
||||
var REGEXP_ATTR_VALUE_COLON = /:?/img;
|
||||
var REGEXP_ATTR_VALUE_NEWLINE = /&newline;?/img;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_1 = /\/\*|\*\//mg;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_2 = /^[\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;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_1 = /^((https?:\/)?\/)/;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\/\*|\*\//mg;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((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;
|
||||
var REGEXP_DEFAULT_ON_TAG_ATTR_5 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/ig;
|
||||
|
||||
@@ -30,25 +30,26 @@ describe('test XSS', function () {
|
||||
assert.equal(xss('<<<a>>b</a><x>'), '<<<a>>b</a><x>');
|
||||
|
||||
// 过滤不在白名单中的属性
|
||||
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 oo="1" xx="2" title="3">yy</a>'), '<a title="3">yy</a>');
|
||||
assert.equal(xss('<a title xx oo>pp</a>'), '<a title>pp</a>');
|
||||
assert.equal(xss('<a title "">pp</a>'), '<a title>pp</a>');
|
||||
assert.equal(xss('<a t="">'), '<a>');
|
||||
|
||||
// 属性内的特殊字符
|
||||
assert.equal(xss('<a href="\'<<>>">'), '<a href="\'<<>>">');
|
||||
assert.equal(xss('<a href=""">'), '<a href=\"\"\">');
|
||||
assert.equal(xss('<a h=href="oo">'), '<a>');
|
||||
assert.equal(xss('<a h= href="oo">'), '<a href="oo">');
|
||||
assert.equal(xss('<a title="\'<<>>">'), '<a title="\'<<>>">');
|
||||
assert.equal(xss('<a title=""">'), '<a title=\"\"\">');
|
||||
assert.equal(xss('<a h=title="oo">'), '<a>');
|
||||
assert.equal(xss('<a h= title="oo">'), '<a title="oo">');
|
||||
assert.equal(xss('<a title="javascript&colonalert(/xss/)">'), '<a title="javascript:alert(/xss/)">');
|
||||
|
||||
// 自动将属性值的单引号转为双引号
|
||||
assert.equal(xss('<a href=\'abcd\'>'), '<a href="abcd">');
|
||||
assert.equal(xss('<a href=\'"\'>'), '<a href=""e;">');
|
||||
assert.equal(xss('<a title=\'abcd\'>'), '<a title="abcd">');
|
||||
assert.equal(xss('<a title=\'"\'>'), '<a title=""e;">');
|
||||
|
||||
// 没有双引号括起来的属性值
|
||||
assert.equal(xss('<a href=home>'), '<a href="home">');
|
||||
assert.equal(xss('<a href=abc("d")>'), '<a href="abc("e;d"e;)">');
|
||||
assert.equal(xss('<a href=abc(\'d\')>'), '<a href="abc(\'d\')">');
|
||||
assert.equal(xss('<a title=home>'), '<a title="home">');
|
||||
assert.equal(xss('<a title=abc("d")>'), '<a title="abc("e;d"e;)">');
|
||||
assert.equal(xss('<a title=abc(\'d\')>'), '<a title="abc(\'d\')">');
|
||||
|
||||
// 单个闭合标签
|
||||
assert.equal(xss('<img src="#"/>'), '<img src="#" />');
|
||||
@@ -63,7 +64,7 @@ describe('test XSS', function () {
|
||||
it('#white list', function () {
|
||||
|
||||
// 过滤所有标签
|
||||
assert.equal(xss('<a href="xx">bb</a>', {whiteList: {}}), '<a href="xx">bb</a>');
|
||||
assert.equal(xss('<a title="xx">bb</a>', {whiteList: {}}), '<a title="xx">bb</a>');
|
||||
assert.equal(xss('<hr>', {whiteList: {}}), '<hr>');
|
||||
// 增加白名单标签及属性
|
||||
assert.equal(xss('<ooxx yy="ok" cc="no">uu</ooxx>', {whiteList: {ooxx: ['yy']}}), '<ooxx yy="ok">uu</ooxx>');
|
||||
@@ -143,8 +144,11 @@ describe('test XSS', function () {
|
||||
|
||||
assert.equal(xss('<a href="javas/**/cript:alert(\'XSS\');">'), '<a href="#">');
|
||||
|
||||
assert.equal(xss('<a href="javascript">'), '<a href="javascript">');
|
||||
assert.equal(xss('<a href="javascript">'), '<a href="#">');
|
||||
assert.equal(xss('<a href="/javascript/a">'), '<a href="/javascript/a">');
|
||||
assert.equal(xss('<a href="/javascript/a">'), '<a href="/javascript/a">');
|
||||
assert.equal(xss('<a href="http://aa.com">'), '<a href="http://aa.com">');
|
||||
assert.equal(xss('<a href="https://aa.com">'), '<a href="https://aa.com">');
|
||||
|
||||
// 这个暂时不知道怎么处理
|
||||
//assert.equal(xss('¼script¾alert(¢XSS¢)¼/script¾'), '');
|
||||
@@ -155,19 +159,19 @@ describe('test XSS', function () {
|
||||
// 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">');
|
||||
assert.equal(xss('<a href="a
b">'), '<a href="#">');
|
||||
assert.equal(xss('<a href="a&NewLineb">'), '<a href="#">');
|
||||
assert.equal(xss('<a href="javasc
ript:alert(1)">'), '<a href="#">');
|
||||
|
||||
// data URI 协议过滤,只允许 data: image/*
|
||||
// data URI 协议过滤
|
||||
assert.equal(xss('<a href="data:">'), '<a href="#">');
|
||||
assert.equal(xss('<a href="d a t a : ">'), '<a href="#">');
|
||||
assert.equal(xss('<a href="data: html/text;">'), '<a href="#">');
|
||||
assert.equal(xss('<a href="data:html/text;">'), '<a href="#">');
|
||||
assert.equal(xss('<a href="data:html /text;">'), '<a href="#">');
|
||||
assert.equal(xss('<a href="data: image/text;">'), '<a href="data: image/text;">');
|
||||
assert.equal(xss('<a href="data: image/text;">'), '<a href="#">');
|
||||
assert.equal(xss('<img src="data: aaa/text;">'), '<img src="#">');
|
||||
assert.equal(xss('<img src="data:image/png; base64; ofdkofiodiofl">'), '<img src="data:image/png; base64; ofdkofiodiofl">');
|
||||
assert.equal(xss('<img src="data:image/png; base64; ofdkofiodiofl">'), '<img src="#">');
|
||||
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user