1.反射型
LOW:
没有过滤,直接键入PAYLOAD
查看源码
这里没有任何过滤,使用htmlspecialchars()过滤
结果不弹窗
MEDIUM:
LOW等级的方法不奏效了
观察输出可能是过滤了<script>标签
审查元素发现确实过滤了<script>标签
使用大小写混写绕过 <scrIpt>alert(1)</sCript>
查看代码发现只过滤了<script>
而且只过滤了一次,所以可以嵌套<script>绕过
<scr<script>ipt>alert(1)</scrip<script>t>
还可以使用htmlspecialchars()过滤
HIGH:
MEDIUM也不会弹窗了
发现发生了过滤,而且script都被过滤了
输入<img src=1 onerror=alert(1)>
查看源码,发现仅仅是过滤了script
过滤时不推荐使用黑名单,基本上总有办法绕过
IMPOSSIBLE:
发现输入的代码变成了HTML实体查看源码发现使用了htmlspecialchars处理,并且使用了token,防止了CSRF
2.存储型
LOW:
这里Name的maxlength是10,可以审查元素给修改成大的值
输入<script>alert(1)</script>弹窗出现两次,说明在Name和Message处都存在存储型XSS
查看源码发现只是去除了两端的空白字符
使用htmlspecialchars处理
MEDIUM:
使用LOW的PAYLOAD已经不行了
还是过滤了script
在Name处成功弹窗,Message处被过滤了
查看源码
HIGH:
查看源码
IMPOSSIBLE:
直接看源码
对name,message都过滤了
3.DOM型
LOW:
直接弹窗
查看源码
emmm..毛都没有..
MEDIUM:
输入PAYLOAD
发现没有弹窗,查看元素
发现在<option>标签里,再次尝试一次,这次闭合<option>标签
还是没又弹窗,中再次查看元素
再次向上闭合<select>标签
成功弹窗
查看源码
如果出现<script,会重定向到English
HIGH:
输入MEDIUM的PAYLOAD
发现重定向到English了
URL中 #后面的字符会被当做定位标识符,所以不会被传递给服务器,只与浏览器交互,而DOM型XSS也是只与浏览器交互
所以尝试#,修改完#之后,浏览器不会重载,需要手动刷新
审查元素
剩下就是类似于MEDIUM等级,闭合标签
查看源码
只允许French,English,German,Spanish四种语言
IMPOSSIBLE:
直接看源码
告诉我们代码防御在客户端
查看index.php
如果是impossible等级的,不会解码URL,直接置为空,并不会进行解码
果然没有解码
将上面代码注释
注意:
防御XSS即使用了htmlspecialchars,只要我们在前端又进行了操作
也可能有危险,请看下面的例子
<html>
<?php
$a=htmlspecialchars($_GET['id']);
//$a=$_GET['id'];
echo 'id: '.$a;
echo '</br>';
echo 'urldecodeId: '.urldecode($a);
echo '</br>';
?>
html: <input type='text' value="<?=$a?>"/>
<br/>
<script>
var lang = document.location.href.substring(document.location.href.indexOf("id="));
document.write('JS: '+lang);
document.write('<br/>');
document.write('decodeURI: '+decodeURI(lang));
</script>
</html>
最后的转码会造成XSS