先说个故事吧,在上一篇,我还想说这个案例。其实什么叫攻击,很简单。获取攻击者想要的信息,就黑成功了。抓到一个tomcat漏洞(这不是我说的,一个
认识的人说的),上传一个jsp,里面模拟httpclient,下载一个木马,运行。ok,搞定了。所以,没有绝对的安全。
今天,泥瓦匠带你们认识下xss,然后关于怎么防御的问题。至于防御的话,仁者见仁智者见智。尔等啥都不配不上的就绰见,望各位阅读者相互讨论。泥瓦匠目前是搞java的,所以例子上java比较多。
q: 什么是xss? 为啥有这个呢?
a: 全名:cross site script,中文名:跨站脚本攻击。顾名思义,是指“html注入”纂改了网页,插入恶意的脚本,从而在用户用浏览网页的时候,控制用户浏览器的一种攻击。
xss根据攻击的稳定性可分为三种:反射型xss, 存储型xss,dom based xss.

再来了解下xss,是如何攻击?泥瓦匠这时候想到一句话:知己知彼,百战百胜吧。这攻击我们不会很详细解释,毕竟想说的是xss防御嘛。首先,泥瓦匠要介绍下的是:
xss
playload,所谓用以完成各种具体的功能的恶意脚本。这时候我想到了黑客精神中的小插曲,现在所谓的“黑客”不是真正的黑客,而是称为脚本小子
(script kid)。常见的一个xss
playload,就是通过读取浏览器的cookie对象,从而发起了‘cookie劫持’攻击。这个泥瓦匠会教你们去防御哈,其中cookie的
‘httponly’标识可以防止哦。
强大的xss playload可以做以下的事情哈:1、构造 get 与 post 请求 2、各种钓鱼 3、识别用户浏览器 等等
q&a
q:什么叫做钓鱼呢?
a:顾名思义,愿者上钩,这里做贬义用法。比如,人家用一个假的弹出框,或者假的页面让你输入qq信息,或者啥账号信息。其实你一输入人家服务器获取到你的账户密码了。这就是鱼儿上钩了。 如图比喻:
兵来将挡,水来土掩。泥瓦匠在web安全上,想提醒大家的是:“再高的树,猴子也能爬上去。”因此,我们考虑的地方有些默认都给你做好了,有些需要我们自己去关心,去设置。
其实在看不到的地方很多已经对抗xss做了些措施。比如各种浏览器等。
一、按着上面的思路,泥瓦匠先聊下cookie,一个cookie,我们是这样使用的:
1、浏览器下服务器发送请求,准备获取cookie
2、服务器返回发送cookie头,向客户端浏览器写入cookie。(注意哦,这里是浏览器,不要当成什么浏览器内核)
3、在cookie到期前,浏览器所有页面,都会发送cookie。
这就意味着,我们cookie不能乱用。就像session一样,所以在使用的时候,要注意下。有时候cooike在用于记住密码的时候,千万要注意要将
cookie设置httponly属性为ture。这里我以springmvc为例子。如果用到cookie的时候,应该这样:
1
2
3
4
5
6
7
<code> </code><code>// create cookie and set it in response</code>
<code>cookie cookie1 = new cookie("cookie1", "cookievaluehttponly");</code>
<code>cookie cookie2 = new cookie("cookie2", "cookievalue");</code>
<code>cookie1.sethttponly(true);</code>
<code>response.addcookie(cookie1);</code>
<code>response.addcookie(cookie2);</code>
截个controller整个代码看看:
我们打开浏览器可以看到下面这种结果,访问url这个controller层,打开firebug查看:
二、输入校验
输入校验的逻辑必须放在服务端中实现。如果用js进行的话,容易被攻击者绕过去。所以普遍的做法是,类似很多代码一样进行double check:”客户端js校验和服务端校验一起,这样客户端js校验会阻挡大部分甚至说99%的用户的误操作。”
在xss防御上,我们需要对用户输入的一些特殊字符校验,过滤或者是编码。这种输入校验的方式成为“xss filter”。首先我们在配置文件中,
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<code>public class xsshttpservletrequestwrapper extends httpservletrequestwrapper</code>
<code>{</code>
<code> </code><code>public xsshttpservletrequestwrapper(httpservletrequest request)</code>
<code> </code><code>{</code>
<code> </code><code>super(request);</code>
<code> </code><code>}</code>
<code> </code><code>public string[] getparametervalues(string parameter)</code>
<code> </code><code>string[] values = super.getparametervalues(parameter);</code>
<code> </code><code>if (values==null)</code>
<code> </code><code>{</code>
<code> </code><code>return null;</code>
<code> </code><code>}</code>
<code> </code><code>int count = values.length;</code>
<code> </code><code>string[] encodedvalues = new string[count];</code>
<code> </code><code>for (int i = 0; i < </code><code>count</code><code>; i++)</code>
<code> </code><code>encodedvalues[i] = cleanxss(values[i]);</code>
<code> </code><code>return encodedvalues;</code>
<code> </code><code>public string getparameter(string parameter)</code>
<code> </code><code>string </code><code>value</code> <code>= </code><code>super</code><code>.getparameter(parameter);</code>
<code> </code><code>if (value == null)</code>
<code> </code><code>return cleanxss(value);</code>
<code> </code><code>public string getheader(string name)</code>
<code> </code><code>string </code><code>value</code> <code>= </code><code>super</code><code>.getheader(name);</code>
<code> </code><code>/**</code>
<code> </code><code>* @title: cleanxss</code>
<code> </code><code>* @description: you'll need to remove the spaces from the html entities below</code>
<code> </code><code>* @param @param value</code>
<code> </code><code>* @param @return</code>
<code> </code><code>* @return string</code>
<code> </code><code>*/</code>
<code> </code><code>private string cleanxss(string value)</code>
<code> </code><code>value</code> <code>= value.replaceall("<", "& lt;").replaceall(">", "& gt;");</code>
<code> </code><code>value = value.replaceall("\\(", "& #40;").replaceall("\\)", "& #41;");</code>
<code> </code><code>value = value.replaceall("'", "& #39;");</code>
<code> </code><code>value = value.replaceall("eval\\((.*)\\)", "");</code>
<code> </code><code>value = value.replaceall("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");</code>
<code> </code><code>value = value.replaceall("script", "");</code>
<code> </code><code>return value;</code>
<code>}</code>
三、输出校验
一般来说,除了富文本之外,在变量输出到html页面,可以使用编码或者转义的方式来防御xss攻击。这是一种各家委婉的方式吧。
用兵之道在于,如何正确的使用,才能以少胜多。web安全这场战争也一样,所以要如何正确的使用xss防御。