Home >Backend Development >PHP Tutorial >PHP htmlspecialchars不能防御前端innerHTML产生的XSS注入

PHP htmlspecialchars不能防御前端innerHTML产生的XSS注入

WBOY
WBOYOriginal
2016-06-23 13:15:411255browse

不要在JS里直接用innerHTML输出未经JS过滤的用户内容,
即使这些内容已经经过服务器端PHP的htmlspecialchars或者HTMLPurifier过滤.
比如下面的代码,页面将alert弹出字符串/xss/,因为JS会把变量中的Unicode字符\u003c和\u003e转换成输出.

//PHP htmlspecialchars不能防御前端innerHTML产生的XSS注入
$xss = '\u003cimg src=1 onerror=alert(/xss/)\u003e';
//XSS
$xss = '\u003ca href=javascript:alert(String.fromCharCode(88,83,83))\u003eXSS\u003c/a\u003e';
header('Content-Type: text/html;charset=utf-8');
?>



<script> <br /> // PHP的htmlspecialchars不能过滤\u003c和\u003e,经过JS赋值后,Unicode字符\u003c和\u003e被转换成<和>. <br /> var xss = '<?php echo htmlspecialchars($xss, ENT_QUOTES, 'UTF-8'); ?>'; <br /> console.log(xss); <br /> //$("#xss").html(xss); //能够执行alert(/xss/) document.getElementById("xss").innerHTML = xss; <br /> //$("#xss").html(xss.replace(/, "<").replace(/>/g, ">")); //不能执行alert(/xss/) <br /> //$("#xss").text(xss); //不能执行alert(/xss/) document.getElementById("xss").innerText = xss; <br /> </script>
$(#xss).append(xss)跟$("#xss").html(xss)输出的都是HTML.

解决方法:
http://segmentfault.com/q/1010000004067521
你说的对,毕竟很多时候要把AJAX加载的数据用innerHTML添加到页面.
值得注意的是,innerHTML本质也是输出HTML,
所以我们可以在输出前用JS像PHP的htmlspecialchars那样
把特殊字符(&,",',)替换为HTML实体(&"'<>).
或者干脆直接用innerText(IE)和textContent(Firefox),也就是jQuery的text()来输出文本内容.
Firefox不支持IE的innerText,但支持textContent.
StackOverflow上找到的两个实现:
function htmlspecialchars(str) {
    return str
        .replace(/&/g, "&")
        .replace(/, "<")
.replace(/>/g, ">")
        .replace(/"/g, """)
        .replace(/'/g, "'");
}
function htmlspecialchars(str) {
    var map = {
        '&': '&',
        '         '"': '"',
        "'": '''
    };
    return str.replace(/[&"']/g, function(k) { return map[k]; });
}
其中g表示全局(global)替换的意思,也就是把字符串中的所有匹配的内容都进行替换.

不过JS模仿PHP的htmlspecialchars是一刀切的方法,数据将丧失HTML特性.
请教下,对于前端AJAX(PJAX)过来后的HTML数据大家是怎么过滤XSS输出的呢?
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn