xss的介绍就不说了,这里记录一下自己在学习xss的时候的一些历程。
预防xss归根结底就是防止浏览器执行非预期的代码,一般来说只要有输入的地方就有可能会产生xss。
1.初步了解
一开始在接触xss的时候,在如何预防xss这方面看到的大多数的解决办法都是过滤标签,比如<script>,<a>,<img>,<iframe>等标签。
<script>标签这个很好理解,在闭合的<script>标签中可以执行js代码。
<a>标签可以通过href属性进行攻击,
<a href="javascript:void(alert(1))">aaaaa</a>
<img>标签可以通过src和onerror配合使用来完成xss,
<img src=1 οnerrοr="alert(1)"></img>
<iframe>标签也是可以通过src属性进行xss,
<iframe src=javascript:alert('XSS')></iframe>
看了很多资料都在说如何对这类的标签进行过滤,如果只是过滤这些个标签就能防御xss(其实过滤这些标签仅仅只能防御及手术情况),那为什么不能只过滤'<','>',这样不是更简单,因为有着这个疑问,才在xss上有了更进一步的了解。
2.进一步了解
然后又去找资料,又看到了需要过滤 '<', '>', '&', '"','/'前面两个上面已经分析过了,但是后面几个是什么鬼?
先看 '"',举个例子,你有这样一行代码 <input name="test", value="abc">,而这个input的value刚好是动态生成的(用户输入的值),我们将值aaa替换成
'"><img src=1 οnerrοr="alert(1)">'
完整的html就变成了这样
<input name="test", value=""><img src=1 οnerrοr="alert(1)">">
嗯,没错现在浏览器成功弹出了一个对话框。
html中在标签内或者标签属性内可以识别html编码(可以参考我的另一篇博文https://blog.csdn.net/u011877410/article/details/80681279)
html中的字符可以使用十六进制或者十进制的asiic码替换,只不过,十进制前面加&#,十六进制&#x。
就拿16进制举例
<img src=1 οnerrοr="javascript:alert('1')">
可以用<img src=1 οnerrοr="javascript:alert('1')">替代。
转义符'/'是标签闭合必不可少的符号,所以也应该要过滤。
3.进阶
我们可以从前后端分开来看这个问题。
后端:
1.后端输出js
有一个变量是a,a的值是由后端获取那么,那么很轻松就可以完成xss。
var a = "";
a = getDataFromEnd();
//如果从后端获取的值为'";alert("xss")'
//a就变为如下值
a = "";alert("xss")
对获取的值进行js编码
2.后端输出html
<div id="add">
elements
<div>
//可以在上面的div标签里面添加元素
//直接添加<img src=1 οnerrοr="alert(1)">
<div id="add">
<img src=1 οnerrοr="alert(1)">
</div>
这个可以用白名单规避,限制输出的html的标签,限制标签属性。
3.后端输出标签属性
直接让标签闭合并且插入攻击的代码
//原本的html
<input name="abc" value="">
//value的值是从后端获取的
//如果value的是'"><img src=1 οnerrοr="alert(1)">'
//整个html变为
<input name="abc" value=""><img src=1 οnerrοr="alert(1)">">
将输出到标签属性中的值进行html编码
4.后端输出动态执行js
<img src="xxx.jpg" οnlοad="alert(var)">
//如果var的内容是动态传入的话
//那么可以填充任意攻击代码
//比如传入');alert(100)'
//源代码变为
<img src="xxx.jpg" οnlοad="alert();alert(100);)">
//之前只是想输出一个值,现在有多输出了一个值
对传入内容进行js编码
4.总结
xss防范总结一句话就是不要信任用户输入的任何内容,如果对安全要求不是很高,那简单过滤几个标签和一些特殊字符就行。