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