时间:2021-07-01 10:21:17 帮助过:20人阅读
Update20151202:
感谢大家的关注和回答,目前我从各种方式了解到的防御方法,整理如下:
PHP直接输出html的,可以采用以下的方法进行过滤
:1.htmlspecialchars函数 2.htmlentities函数 3.HTMLPurifier.auto.php插件 4.RemoveXss函数(百度可以查到)
PHP输出到JS代码中,或者开发Json API的,则需要前端在JS中进行过滤
:输出文本内容 2.必须要用innerHTML等等函数,则需要做类似php的htmlspecialchars的过滤(参照@eechen的答案)1.尽量使用innerTehttp://bbs.wdzj.com/xt(IE)和tehttp://bbs.wdzj.com/xtContent(Firefohttp://bbs.wdzj.com/x),也就是jQuery的tehttp://bbs.wdzj.com/xt()来
其它的通用的补充性防御手段
输出html时,加上Content Security Policy的Http Header (作用:可以防止页面被XSS攻击时,嵌入第三方的脚本文件等) (缺陷:IE或低版本的浏览器可能不支持) 2.在设置Cookie时,加上HttpOnly参数 (作用:可以防止页面被XSS攻击时,Cookie信息被盗取,可兼容至IE6) (缺陷:网站本身的JS代码也无法操作Cookie,而且作用有限,只能保证Cookie的安全) 3.在开发API时,检验请求的Referer参数 (作用:可以在一定程度上防止CSRF攻击) (缺陷:IE或低版本的浏览器中,Referer参数可以被伪造)1.在
大概就是这些了,大家还有什么别的思路,欢迎补充!
——————————————————————————————————————————————————
原问题如下:
1.PHP如何完美(或者尽可能完美地)防御XSS攻击(比htmlspecialchars更完善的)?
2.我在想是不是防御XSS最好在前端做(毕竟JS在前端解析字符串都有坑啊)?
3.有木有什么解决方案或者思路啊,什么都行?
最近都在研究XSS防御的问题。
毕竟,比如用户注册的API,可能被Hacker利用,强行提交了""这样的用户名。
然后WEB前端怎么都要有显示用户名的地方吧。。。
于是。。。Boom。。。
直入重点:
我看到很多应对XSS的防御方案都是PHP的htmlentities函数或者htmlspecialchars。
随意百度了下,貌似ThinkPHP3.http://bbs.wdzj.com/x默认就是用的htmlspecialchars。
比如:$str = htmlspecialchars($str, ENT_QUOTES);//替换掉<>&'"这5个字符
但是,只替换掉那几个字符真的够吗?
然后我发现了这个文章:
http://tieba.baidu.com/p/3003719171
使用\u003c\u003e在JS字符串中会被解释成<>的特性进行XSS攻击。。。
卧槽。。。
然后我想到了JS里的eval等等函数简直是无底洞。。。
然后我发现了这个文章:
http://www.2cto.com/Article/201310/251830.html
使用各种编码,各种手段执行JS,简直丧心病狂。
比如:
啊!CAO。
我开始怀疑整个世界了。。。
所以,
我的问题是:
1.PHP如何完美(或者尽可能完美地)防御XSS攻击(比htmlspecialchars更完善的)?
2.我在想是不是防御XSS最好在前端做(毕竟JS在前端解析字符串都有坑啊)?
3.有木有什么解决方案或者思路啊,什么都行?
Update20151201:
能不要再复制粘贴答案,or迷信htmlspecialchars是无敌的了好嘛?
\u003cimg src=1 onerror=alert(/http://bbs.wdzj.com/xss/)\u003e里的任何一个字符都是不会被htmlspecialchars处理的。
自己看图,对,就是你!
Update20151202:
感谢大家的关注和回答,目前我从各种方式了解到的防御方法,整理如下:
PHP直接输出html的,可以采用以下的方法进行过滤
:1.htmlspecialchars函数 2.htmlentities函数 3.HTMLPurifier.auto.php插件 4.RemoveXss函数(百度可以查到)
PHP输出到JS代码中,或者开发Json API的,则需要前端在JS中进行过滤
:输出文本内容 2.必须要用innerHTML等等函数,则需要做类似php的htmlspecialchars的过滤(参照@eechen的答案)1.尽量使用innerTehttp://bbs.wdzj.com/xt(IE)和tehttp://bbs.wdzj.com/xtContent(Firefohttp://bbs.wdzj.com/x),也就是jQuery的tehttp://bbs.wdzj.com/xt()来
其它的通用的补充性防御手段
输出html时,加上Content Security Policy的Http Header (作用:可以防止页面被XSS攻击时,嵌入第三方的脚本文件等) (缺陷:IE或低版本的浏览器可能不支持) 2.在设置Cookie时,加上HttpOnly参数 (作用:可以防止页面被XSS攻击时,Cookie信息被盗取,可兼容至IE6) (缺陷:网站本身的JS代码也无法操作Cookie,而且作用有限,只能保证Cookie的安全) 3.在开发API时,检验请求的Referer参数 (作用:可以在一定程度上防止CSRF攻击) (缺陷:IE或低版本的浏览器中,Referer参数可以被伪造)1.在
大概就是这些了,大家还有什么别的思路,欢迎补充!
——————————————————————————————————————————————————
原问题如下:
1.PHP如何完美(或者尽可能完美地)防御XSS攻击(比htmlspecialchars更完善的)?
2.我在想是不是防御XSS最好在前端做(毕竟JS在前端解析字符串都有坑啊)?
3.有木有什么解决方案或者思路啊,什么都行?
最近都在研究XSS防御的问题。
毕竟,比如用户注册的API,可能被Hacker利用,强行提交了""这样的用户名。
然后WEB前端怎么都要有显示用户名的地方吧。。。
于是。。。Boom。。。
直入重点:
我看到很多应对XSS的防御方案都是PHP的htmlentities函数或者htmlspecialchars。
随意百度了下,貌似ThinkPHP3.http://bbs.wdzj.com/x默认就是用的htmlspecialchars。
比如:$str = htmlspecialchars($str, ENT_QUOTES);//替换掉<>&'"这5个字符
但是,只替换掉那几个字符真的够吗?
然后我发现了这个文章:
http://tieba.baidu.com/p/3003719171
使用\u003c\u003e在JS字符串中会被解释成<>的特性进行XSS攻击。。。
卧槽。。。
然后我想到了JS里的eval等等函数简直是无底洞。。。
然后我发现了这个文章:
http://www.2cto.com/Article/201310/251830.html
使用各种编码,各种手段执行JS,简直丧心病狂。
比如:
啊!CAO。
我开始怀疑整个世界了。。。
所以,
我的问题是:
1.PHP如何完美(或者尽可能完美地)防御XSS攻击(比htmlspecialchars更完善的)?
2.我在想是不是防御XSS最好在前端做(毕竟JS在前端解析字符串都有坑啊)?
3.有木有什么解决方案或者思路啊,什么都行?
Update20151201:
能不要再复制粘贴答案,or迷信htmlspecialchars是无敌的了好嘛?
\u003cimg src=1 onerror=alert(/http://bbs.wdzj.com/xss/)\u003e里的任何一个字符都是不会被htmlspecialchars处理的。
自己看图,对,就是你!
这个问题我们还是先来请教一下砖家……
现在马上为我们连线场外的砖家……
嘟嘟嘟……
砖家您好,请问这位同学的问题您怎么看?
砖家:我趴在窗户上看……
……@#%&*!~~(@$%……
好了,原来砖家是说最近雾霾严重,所以他只能趴在窗户上看这个问题……
现在请听专家解读:
魔亦有道。
有专门的研究这些东西的,任何事只有专业领域的人做才会更有效率。
使用HTMLPurifier
才是终极理想。
http://www.http://bbs.wdzj.com/xcoder.cn/indehttp://bbs.wdzj.com/x.php/archives/971
http://willko.iteye.com/blog/475493
http://www.piaoyi.org/php/HTML-Purifier-PHP-http://bbs.wdzj.com/xss.html
http://www.edu.cn/ji_shu_ju_le_bu_1640/20080717/t20080717_310285.shtml
http://www.111cn.net/phper/phpanqn/78018.htm
http://security.ctocio.com.cn/securitycomment/54/8222554.shtml
其实我还想说,我不希望防XSS这种事情交给前端,模板语言来做,对于前端,给她用什么就用什么,用的不爽自己适当的做变量调节就可以了。给她们用,让她们用的爽,用的简单,这是我们好男人的责任和义务,大家说对不对啊,嘻嘻。
首先,我想说,不要用你的无知来挑战大家
这是道高一尺魔高一丈的东西
html中的编码:
< 进行编码
html十进制: <
html十六进制:http://bbs.wdzj.com/x3c;
url: %3C
base64: PA==
javascript中的编码:
< 进行编码
八进制:\74
十六进制:\http://bbs.wdzj.com/x3c
unicode:\u003c
当然 htmlspecialchars 肯定是不行的,只能进行简单的处理,要不然还讨论什么http://bbs.wdzj.com/xss了
The translations performed are:
'&' (ampersand) becomes '&'
'"' (double quote) becomes '"' when ENT_NOQUOTES is not set.
"'" (single quote) becomes ''' (or ') only when ENT_QUOTES is set.
'<' (less than) becomes '<'
'>' (greater than) becomes '>'
上面代码还可以这样写
test
test
test
click
test
但关键是,你确定你的那些代码可以提交吗?你要确定了再拿出来说
比如最简单的href加入以下代码基本上歇菜了
你到底有没有测试过,就说你提到的那些场景能够绕过htmlspecialchars呀,实践出真知.
补充:
你说的对,毕竟很多时候要把AJAX加载的数据用innerHTML添加到页面.
值得注意的是,innerHTML本质也是输出HTML,
所以我们可以在输出前用JS像PHP的htmlspecialchars那样
把特殊字符(&,",',<,>)替换为HTML实体(&"'<>
).
或者干脆直接用innerTehttp://bbs.wdzj.com/xt(IE)和tehttp://bbs.wdzj.com/xtContent(Firefohttp://bbs.wdzj.com/x),也就是jQuery的tehttp://bbs.wdzj.com/xt()来输出文本内容.
StackOverflow上找的两个实现:
function escapeHtml(tehttp://bbs.wdzj.com/xt) {
return tehttp://bbs.wdzj.com/xt
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function escapeHtml(tehttp://bbs.wdzj.com/xt) {
var map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return tehttp://bbs.wdzj.com/xt.replace(/[&<>"']/g, function(m) { return map[m]; });
}
方法一,利用php htmlentities函数
php防止XSS跨站脚本攻击的方法:是针对非法的HTML代码包括单双引号等,使用htmlspecialchars()函数 。
在使用htmlspecialchars()函数的时候注意第二个参数, 直接用htmlspecialchars($string) 的话,第二个参数默认是ENT_COMPAT,函数默认只是转化双引号(“), 不对单引号(‘)做转义。
所以,htmlspecialchars函数更多的时候要加上第二个参数, 应该这样用: htmlspecialchars($string,ENT_QUOTES).当然,如果需要不转化如何的引号,用htmlspecialchars($string,ENT_NOQUOTES)。
另外, 尽量少用htmlentities, 在全部英文的时候htmlentities和htmlspecialchars没有区别,都可以达到目的.但是,中文情况下, htmlentities却会转化所有的html代码,连同里面的它无法识别的中文字符也给转化了。
htmlentities和htmlspecialchars这两个函数对 '之类的字符串支持不好,都不能转化, 所以用htmlentities和htmlspecialchars转化的字符串只能防止XSS攻击,不能防止SQL注入攻击.
所有有打印的语句如echo,print等 在打印前都要使用htmlentities() 进行过滤,这样可以防止Xss,注意中文要写出htmlentities($name,ENT_NOQUOTES,GB2312) 。
方法二,给一个函数
function http://bbs.wdzj.com/xss_clean($data){
// Fihttp://bbs.wdzj.com/x &entity\n;
$data=str_replace(array('&','<','>'),array('&','<','>'),$data);
$data=preg_replace('/(*\w+)[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]+;/u','$1;',$data);
$data=preg_replace('/(http://bbs.wdzj.com/x*[0-9A-F]+);*/iu','$1;',$data);
$data=html_entity_decode($data,ENT_COMPAT,'UTF-8');
// Remove any attribute starting with "on" or http://bbs.wdzj.com/xmlns
$data=preg_replace('#(<[^>]+?[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20"\'])(?:on|http://bbs.wdzj.com/xmlns)[^>]*+>#iu','$1>',$data);
// Remove javascript: and vbscript: protocols
$data=preg_replace('#([a-z]*)[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*=[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*([`\'"]*)[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*j[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*a[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*v[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*a[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*s[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*c[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*r[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*i[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*p[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*t[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*:#iu','$1=$2nojavascript...',$data);
$data=preg_replace('#([a-z]*)[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*=([\'"]*)[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*v[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*b[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*s[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*c[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*r[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*i[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*p[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*t[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*:#iu','$1=$2novbscript...',$data);
$data=preg_replace('#([a-z]*)[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*=([\'"]*)[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*-moz-binding[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*:#u','$1=$2nomozbinding...',$data);
// Only works in IE:
$data=preg_replace('#(<[^>]+?)style[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*=[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*[`\'"]*.*?ehttp://bbs.wdzj.com/xpression[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*\([^>]*+>#i','$1>',$data);
$data=preg_replace('#(<[^>]+?)style[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*=[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*[`\'"]*.*?behaviour[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*\([^>]*+>#i','$1>',$data);
$data=preg_replace('#(<[^>]+?)style[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*=[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*[`\'"]*.*?s[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*c[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*r[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*i[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*p[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*t[\http://bbs.wdzj.com/x00-\http://bbs.wdzj.com/x20]*:*[^>]*+>#iu','$1>',$data);
// Remove namespaced elements (we do not need them)
$data=preg_replace('#*\w+:\w[^>]*+>#i','',$data);
// http://www.111cn.net/
do{// Remove really unwanted tags
$old_data=$data;
$data=preg_replace('#*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|http://bbs.wdzj.com/xml)[^>]*+>#i','',$data);
}while($old_data!==$data);
// we are done...
return $data;
}
想要“完美”防御XSS,就要每个开发都完全了解XSS的知识,在合适的场景用合适的方案来编码
推荐参考:
https://www.owasp.org/indehttp://bbs.wdzj.com/x.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
任何用一个函数/一个库来解决这个问题的努力都是白日做梦。
重新再贴一边:
https://www.owasp.org/indehttp://bbs.wdzj.com/x.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
永远不可能完美防御,但至少可以挡住99%(剩下的1%才是最凶猛的~~~),目前的统一做法是,做好输入检查,良好的编程意识,安全转义,借助第三方安全库。不要信任输入。也不要信任输出。
为什么不用 CSP 直接一了百了呢?