1.输出在HTML页面
例如:有个test.php文件
<?PHP
echo "欢迎您,".$_GET['name'];
?>
用http://localhost/test.php?name=lake<script>alert(123456)</script> 进行访问,用这样的URL将会执行JavaScript的alert函数弹出一个对话框
传入的参数值直接显示在页面,主要就是传入的参数中带有“<”和“>”符号会被浏览器解析,
2.输出在HTML属性中
例如:
<?PHP
echo "<a href=\"".$_GET['name']."\">Enter</a>";
?>
用http://localhost/test2521.php?name=test">Hi</a><script>alert(123456)</script><!--访问
会得到页面:<a href="test">Hi</a><script>alert(123456)</script><!—">Enter</a>
从而出现xss攻击
3.输出在JavaScript代码中
例如:
<?PHP
echo "<script>";
echo "var yourname = '".$_GET['name']."';";
echo "</script>";
?>
分析PHP代码输出的页面,我们很容易构造出XSS攻击测试URL:http://localhost/test2531.php?name=a';alert(123456);//
实际上是我们利用单引号闭合了JavaScript代码的变量赋值,然后再执行我们的alert函数。
得到的返回页面是这样的:
<script>
var yourname = 'a';alert(123456);//';
</script> 然后你又看到那个显示123456表示脚本被执行的演示对话框了。
同样的道理,如果是用的双引号做变量赋值就需要传双引号进去破坏掉原来的JavaScript代码。
4.基于DOM
DOM是Document Object Model(文档对象模型)的缩写。据W3C DOM规范(http://www.w3.org/DOM/),DOM是一种与浏览器,平台,语言无关的接口,使得你可以访问页面其他的标准组件。
简单理解,我们把DOM认为是JavaScript输出的页面,基于DOM的跨站脚本漏洞就是出现在JavaScript代码中的漏洞。请注意,之前的3种输出是属于Web应用程序(CGI程序)代码中的漏洞。
是的,你没有看错,含有JavaScript静态HTML页面也可能会存在XSS漏洞。
以下是一段存在DOM类型跨站脚本漏洞的代码:
<script>
document.write(window.location.search);
</script>
在JS中window.location.search是指URL中?之后的内容,document.write是将内容输出到页面。于是乎,又是一个直接输出到页面的跨站脚本漏洞。好,来构造攻击URL:http://localhost/test2541.php?<script>alert(123456)</script>
但是查看网页源代码,源代码却没变:
这就是DOM,在浏览器的解析中改变页面结构。这种特性检测DOM的跨站脚本漏洞带来了一点麻烦,因为它不能通过页面源代码来判断漏洞,给自动化漏洞检测带来了挑战。
解决方案:
通过这些,发现xss都是由于页面输出数据时,由于没有处理好恶意数据,导致浏览器解析这些恶意造成的。
因此编写安全代码很重要:
对于直接输出在页面xss攻击:
数据需要对“<”、“>”HTML编码:
< 编码为 <
> 编码为 >
输出在HTML属性中的数据不能让属性值被闭合。用双引号(")表示的属性需要编码属性值中的双引号:
" 编码为"
用单引号(')表示的属性需要编码属性值中的单引号:
' 编码为'
对于属性的xss攻击:
要限制img标签的src属性始终以http://或https://开头(白名单匹配)。
对于输出在javascript攻击:
对输出的单引号,双引号进行转义 \' \"
对输出< >进行编码
从而防止浏览器进行解析
String OutStr = "<script>alert('XSS')</script>";
OutStr = OutStr.replaceAll("&","&");
OutStr = OutStr.replaceAll("<","<");
OutStr = OutStr.replaceAll(">",">");
OutStr = OutStr.replaceAll("\"",""");
OutStr = OutStr.replaceAll("\'","'");
OutStr = OutStr.replaceAll("\\(","(");
OutStr = OutStr.replaceAll("\\)",")");
OutStr = OutStr.replaceAll("%","%");
OutStr = OutStr.replaceAll("\\+","+");
OutStr = OutStr.replaceAll("-","-");
out.println(OutStr);
例如:有个test.php文件
<?PHP
echo "欢迎您,".$_GET['name'];
?>
用http://localhost/test.php?name=lake<script>alert(123456)</script> 进行访问,用这样的URL将会执行JavaScript的alert函数弹出一个对话框
传入的参数值直接显示在页面,主要就是传入的参数中带有“<”和“>”符号会被浏览器解析,
2.输出在HTML属性中
例如:
<?PHP
echo "<a href=\"".$_GET['name']."\">Enter</a>";
?>
用http://localhost/test2521.php?name=test">Hi</a><script>alert(123456)</script><!--访问
会得到页面:<a href="test">Hi</a><script>alert(123456)</script><!—">Enter</a>
从而出现xss攻击
3.输出在JavaScript代码中
例如:
<?PHP
echo "<script>";
echo "var yourname = '".$_GET['name']."';";
echo "</script>";
?>
分析PHP代码输出的页面,我们很容易构造出XSS攻击测试URL:http://localhost/test2531.php?name=a';alert(123456);//
实际上是我们利用单引号闭合了JavaScript代码的变量赋值,然后再执行我们的alert函数。
得到的返回页面是这样的:
<script>
var yourname = 'a';alert(123456);//';
</script> 然后你又看到那个显示123456表示脚本被执行的演示对话框了。
同样的道理,如果是用的双引号做变量赋值就需要传双引号进去破坏掉原来的JavaScript代码。
4.基于DOM
DOM是Document Object Model(文档对象模型)的缩写。据W3C DOM规范(http://www.w3.org/DOM/),DOM是一种与浏览器,平台,语言无关的接口,使得你可以访问页面其他的标准组件。
简单理解,我们把DOM认为是JavaScript输出的页面,基于DOM的跨站脚本漏洞就是出现在JavaScript代码中的漏洞。请注意,之前的3种输出是属于Web应用程序(CGI程序)代码中的漏洞。
是的,你没有看错,含有JavaScript静态HTML页面也可能会存在XSS漏洞。
以下是一段存在DOM类型跨站脚本漏洞的代码:
<script>
document.write(window.location.search);
</script>
在JS中window.location.search是指URL中?之后的内容,document.write是将内容输出到页面。于是乎,又是一个直接输出到页面的跨站脚本漏洞。好,来构造攻击URL:http://localhost/test2541.php?<script>alert(123456)</script>
但是查看网页源代码,源代码却没变:
这就是DOM,在浏览器的解析中改变页面结构。这种特性检测DOM的跨站脚本漏洞带来了一点麻烦,因为它不能通过页面源代码来判断漏洞,给自动化漏洞检测带来了挑战。
解决方案:
通过这些,发现xss都是由于页面输出数据时,由于没有处理好恶意数据,导致浏览器解析这些恶意造成的。
因此编写安全代码很重要:
对于直接输出在页面xss攻击:
数据需要对“<”、“>”HTML编码:
< 编码为 <
> 编码为 >
输出在HTML属性中的数据不能让属性值被闭合。用双引号(")表示的属性需要编码属性值中的双引号:
" 编码为"
用单引号(')表示的属性需要编码属性值中的单引号:
' 编码为'
对于属性的xss攻击:
要限制img标签的src属性始终以http://或https://开头(白名单匹配)。
对于输出在javascript攻击:
对输出的单引号,双引号进行转义 \' \"
对输出< >进行编码
从而防止浏览器进行解析
String OutStr = "<script>alert('XSS')</script>";
OutStr = OutStr.replaceAll("&","&");
OutStr = OutStr.replaceAll("<","<");
OutStr = OutStr.replaceAll(">",">");
OutStr = OutStr.replaceAll("\"",""");
OutStr = OutStr.replaceAll("\'","'");
OutStr = OutStr.replaceAll("\\(","(");
OutStr = OutStr.replaceAll("\\)",")");
OutStr = OutStr.replaceAll("%","%");
OutStr = OutStr.replaceAll("\\+","+");
OutStr = OutStr.replaceAll("-","-");
out.println(OutStr);