当前投票最多的答案有从字符串中删除HTML的缺点。如果这不是你想要的(这当然不是问题的一部分),那么我建议使用正则表达式来查找HTML实体(/&[^;]*;/gmi),然后遍历匹配并转换它们。
function decodeHTMLEntities(str) {
if (typeof str !== 'string') {
return false;
}
var element = document.createElement('div');
return str.replace(/&[^;]*;/gmi, entity => {
entity = entity.replace(/</gm, '<');
element.innerHTML = entity;
return element.textContent;
});
}
var encoded_str = `<b>↑ CAN'T HACK ME, BRO</b>`;
var decoded_str = decodeHTMLEntities(encoded_str);
console.log(decoded_str);
关于XSS攻击:
虽然innerHTML不执行<script>标签中的代码,但有可能在*事件属性中运行代码,因此用户传递的字符串可能会利用上面的正则表达式:
&<img src='asdfa' error='alert(`doin\' me a hack`)' />;
因此,有必要将任何<字符转换为它们的<在将它们放入隐藏的div元素之前。
此外,为了覆盖我所有的基础,我将注意到,在全局作用域中定义的函数可以通过在控制台上重新定义它们来重写,因此使用const定义这个函数或将其放在非全局作用域中非常重要。
注意:以下示例中企图利用的漏洞会使堆栈片段编辑器混淆,因为它所做的预处理,所以您必须在浏览器的控制台中运行它,或者在它自己的文件中运行它才能查看结果。
var tests = [
"here's a spade: ♠!",
"&<script>alert('hackerman')</script>;",
"&<img src='asdfa' error='alert(`doin\' me a hack`)' />;",
"<b>↑ CAN'T HACK ME, BRO</b>"
];
var decoded = tests.map(decodeHTMLEntities).join("\n");
console.log(decoded);
结果是:
here's a spade: ♠!
&<script>alert('hackerman')</script>;
&<img src='asdfa' error='alert(`doin' me a hack`)' />;
<b>↑ CAN'T HACK ME, BRO</b>