XSS漏洞【存储型:高危,反射型:低危】
原理概述
黑客通过利用该种类型的漏洞可以在页面上插入自己精心构造的HTML或Js代码,从而在用户浏览网页时,浏览器执行了黑客所插入的恶意代码进而控制用户浏览器。从效果和稳定性上来区分,可分为反射型XSS和存储型XSS,反射型XSS是直接将恶意代码的执行结果反射给浏览器,也就是说黑客往往需要诱使用户点击一个恶意链接才能发起攻击,而存储型XSS是将恶意代码存储在服务器端,然后再输出给前端页面,任何用户访问该页面都会遭受攻击,具有很强的稳定性。
危害
窃取用户cookie,从而获取用户隐私或利用用户身份进一步对网站进行操作
网络钓鱼,盗取各类用户帐号
劫持用户浏览器,从而控制浏览器的行为进行任意操作
进行网页挂马
强制弹出广告页面,恶意刷流量
控制受害者机器向其它目标发起攻击
样例1
<?php
//反射型,黑客可直接提交name=<script>alert(/xss/)</script>
$name=$_GET['name'];
echo "hello"$name;
?>
样例2
//$message通过POST方式获得值,然后存入数据库,所获取的值未经任何安全检查,黑客完全可以提交
//自己精心构造的恶意JS代码,从而造成存储型XSS
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
$message = stripslashes( $message );
$message = mysql_real_escape_string( $message );
$name = mysql_real_escape_string( $name );
//这里$message没有经过任何过滤就存入了数据库
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysql_query( $query ) or die( '<pre>' mysql_error() '</pre>' );
}
?>
//如果在另一个页面,比如显示评论或者消息的页面,又把之前存入数据库的$message显示出来了,那么就会造成存储型XSS,$message在输出时就会在用户浏览器上执行攻击代码
<?php
echo "user:"$username"<BR>";
echo "comment:$message"; //输出了带有XSS攻击代码的$message,攻击代码会在用户浏览器上执行
?>
样例3
<!--DOM型XSS,从效果上看属于反射型XSS,但其形成原因与一般XSS不同,
该类型XSS是由于修改了页面的DOM节点造成的
攻击者可以提交 ' onclick=alert(/xss/)//
-->
<script>
function check(){
var str=documentgetElementById("text")value;
documentgetElementById("t")innerHTML="<a href='"+str+"'>testLink</a>";
</script>
<div id="t"></div>
<input type='text' id="text" value="">
<input type="button" id="s" value="write" onclick="check()">
修复建议
关键性的cookie(如:标识用户登录状态的cookie等,这里用login_in_status_token表示)必须加上httponly属性,样例如下:
//本例为设置cookie有效时长为1小时(即3600秒)
setcookie("login_in_status_token","login_in_status_token_VALUE",time()+3600,"/","test.com",false,true);
//如果启用了HTTPS的话,那么应该开启secure标记
setcookie("login_in_status_token","login_in_status_token_VALUE",time()+3600,"/","test.com",true,true);
对cookie加上httponly属性也不能修复xss漏洞,只能缓解xss攻击,要修复XSS漏洞,首先需要做输入检查,因为XSS漏洞和SQL注入类似,攻击者也需要构造一些特殊的字符,而这些特殊字符可能是正常用户不会用到的,所以有必要进行输入检查
对输入进行检查有个很明显的弊端就是处理用户的数据时没有结合渲染页面的HTML代码,因此对语境的理解并不完整,输入检查虽然有必要,但并不是最好的解决办法。
由于输入检查存在种种弊端,而XSS攻击是发生在前端页面上,所以最好的解决办法是做输出检查,以下用$var表示用户的数据,它在被输出到前端HTML页面中时,会有若干情况,每种情况都需要根据具体场景进行解决