避免XXS攻击的字符转义(escape)和反转义(unescape)
escape和unescape
推荐看讶羽的这篇 underscore 系列之字符实体与 _.escape
这两个函数是为了转义以及反转义html字符串,替换&,<,>,',",和`字符为字符实体,防止浏览器误将其解释为标签,以避免XXS攻击.
我们要转义哪些字符呢?
< 和 > 因为浏览器会把它看成一个标签的开始或结束.
& 浏览器会认为&是一个字符实体的开始.例如
<
浏览器会把它解释成<' 和 " 也需要注意, 例如
function reder(input){
return '<input type="name" value=" '+input+' ''>'
}
//输入 "> <script>alert(1)</script>"
//return -> <input type="name" value=""><script>alert(1)</scripe>
` 在IE低版本中(<=8),反引号可以用于关闭标签.
var escapeMap = {
'&' : '&',
'<' : '<',
'>' : '>',
'"' : '"',
"'" : ''',
'`' : '`'
}
//将对象的key和value反转
_.invert = (obj)=>{
var result = {};
var keys = Object.keys(obj);
for(var i = 0,len = keys.length ;i < len;i++){
result[obj[keys[i]]] = keys[i];
}
return result;
}
var unescapeMap = _.invert(escapeMap);
//为了防止XXS攻击
//转义HTML字符串,替换&,<,>,',"和`字符为字符实体
//以及反转义
//_.escape('Curly , Larry & Moe');
//=>'Curly , Larry & Moe'
const createEscaper = (map) =>{
var escaper = (match)=>map[match];
var source = '(?:'+Object.keys(map).join('|')+')';
//source = "(?:&|<|>|"|'|`)"
//或者"(?:&|<|>|"|'|`)"
var testRegexp = RegExp(source);
//全局搜索,查找所有匹配项,而不是在第一个匹配项后停止
var replaceRegexp = RegExp(source,'g');
return (string)=>{
string = string == null ? '' : '' + string;
//replace 中第二个参数可以是个函数
return testRegexp.test(string) ? string.replace(replaceRegexp,escaper):string;
}
}
_.escape = createEscaper(escapeMap);
_.unescape = createEscaper(unescapeMap);
Last updated
Was this helpful?