11#6 .4 预防session劫持
2- session劫持是一种比较严重的安全威胁,也是一种广泛存在的威胁, 在session技术中,客户端和服务端通过传送session的标识符来维护会话, 但这个标识符很容易就能被嗅探到,从而被其他人利用,这属于一种中间人攻击 。
2+ session劫持是一种广泛存在的比较严重的安全威胁, 在session技术中,客户端和服务端通过session的标识符来维护会话, 但这个标识符很容易就能被嗅探到,从而被其他人利用.它是中间人攻击的一种类型 。
33
4- 本部分通过一个实例来说明何为会话劫持,通过这个实例,读者其实更能理解session的本质 。
4+ 本节将通过一个实例来演示会话劫持,希望通过这个实例,能让读者更好地理解session的本质 。
55##session劫持过程
66我们写了如下的代码来展示一个count计数器:
77
@@ -23,32 +23,41 @@ count.gtpl的代码如下所示:
2323
2424 Hi. Now count:{{.}}
2525
26- 然后我们在浏览器里面刷新可以看到如下代码 :
26+ 然后我们在浏览器里面刷新可以看到如下内容 :
2727
2828![ ] ( images/6.4.hijack.png?raw=true )
2929
30- 不断刷新这个数字会不断的增长,我们把他刷新到6,我们打开chrome的cookie管理器,可以看到如下的设置信息 :
30+ 随着刷新,数字将不断增长,当数字显示为6的时候,打开浏览器(以chrome为例)的cookie管理器,可以看到类似如下的信息 :
3131
3232
3333![ ] ( images/6.4.cookie.png?raw=true )
3434
35- 下面是最关键的,复制chrome地址栏里的地址,然后打开另一个浏览器。 这里我打开了firefox浏览器, 然后打开firefox的cookie模拟插件,新建一个cookie,把上图中cookie模拟到firefox,如下图所示
35+ 下面这个步骤最为关键: 打开另一个浏览器( 这里我打开了firefox浏览器),复制chrome地址栏里的地址到新打开的浏览器的地址栏中。 然后打开firefox的cookie模拟插件,新建一个cookie,把按上图中cookie内容原样在firefox中重建一份:
3636
3737![ ] ( images/6.4.setcookie.png?raw=true )
3838
39- 然后将地址粘贴到其地址栏里,回车后如下图 :
39+ 回车后,你将看到如下内容 :
4040
4141![ ] ( images/6.4.hijacksuccess.png?raw=true )
4242
43- 我们看到我们换了浏览器,但是我们获得了sessionID,然后模拟了这个cookie存储的过程 。这个例子是在同一台计算机上做的,不过即使换用两台来做,其结果也是一样的。此时如果交替点击两个浏览器里的链接你会发现他们其实操纵的是同一个计数器。其实不必惊讶 ,此处firefox盗用了chrome和goserver之间的维持会话的钥匙,即gosessionid,这属于session hijack的一种 。在goserver看来,firefox交给了它一个gosessionid ,由于HTTP协议的无状态性,它无法得知这个gosessionid是从chrome那里“劫持”来的,它依然会去查找对应的session,并执行相关计算。而此时chrome也无法得知自己的保持会话已经被 “劫持”。
43+ 可以看到虽然换了浏览器,但是我们却获得了sessionID,然后模拟了cookie存储的过程 。这个例子是在同一台计算机上做的,不过即使换用两台来做,其结果仍然一样。此时如果交替点击两个浏览器里的链接你会发现它们其实操纵的是同一个计数器。不必惊讶 ,此处firefox盗用了chrome和goserver之间的维持会话的钥匙,即gosessionid,这是一种类型的“会话劫持” 。在goserver看来,它从http请求中得到了一个gosessionid ,由于HTTP协议的无状态性,它无法得知这个gosessionid是从chrome那里“劫持”来的,它依然会去查找对应的session,并执行相关计算。与此同时 chrome也无法得知自己保持的会话已经被 “劫持”。
4444##session劫持防范
4545###cookieonly和token
46- 我们通过上面session劫持的过程可以了解到session一旦被其他人劫持 ,就非常危险,黑客可以模拟用户行为进行很多非法操作。那么如何有效的来防止session劫持呢 ?
46+ 通过上面session劫持的简单演示可以了解到session一旦被其他人劫持 ,就非常危险,劫持者可以假装成被劫持者进行很多非法操作。那么如何有效的防止session劫持呢 ?
4747
48- 其中一个解决方案就是值允许cookie设置,然后设置cookie的httponly为true ,这个属性是设置是否可通过客户端脚本访问这个设置的cookie,第一这个可以防止这个cookie被XSS读取从而引起session劫持。
48+ 其中一个解决方案就是sessionID的值只允许cookie设置,而不是通过URL重置方式设置,同时设置cookie的httponly为true ,这个属性是设置是否可通过客户端脚本访问这个设置的cookie,第一这个可以防止这个cookie被XSS读取从而引起session劫持,第二cookie设置不会像URL重置方式那么容易获取sessionID 。
4949
50- 第二步就是在每个请求里面加上token,类似前面章节里面讲的防止form重复递交类似的功能 ,我们在每个请求里面加上一个隐藏的token,然后每次验证这个token,从而保证用户的请求都是唯一性。
50+ 第二步就是在每个请求里面加上token,实现类似前面章节里面讲的防止form重复递交类似的功能 ,我们在每个请求里面加上一个隐藏的token,然后每次验证这个token,从而保证用户的请求都是唯一性。
5151
52+ h := md5.New()
53+ salt:="astaxie%^7&8888"
54+ io.WriteString(h,salt+time.Now().String())
55+ token:=fmt.Sprintf("%x",h.Sum(nil))
56+ if r.Form["token"]!=token{
57+ //提示登录
58+ }
59+ sess.Set("token",token)
60+
5261
5362###间隔生成新的SID
5463还有一个解决方案就是,我们给session额外设置一个创建时间的值,一旦过了一定的时间,我们销毁这个sessionID,重新生成新的session,这样可以一定程度上防止session劫持的问题。
@@ -61,7 +70,7 @@ count.gtpl的代码如下所示:
6170 sess = globalSessions.SessionStart(w, r)
6271 }
6372
64- session启动后,我们设置了一个值,用于记录生成sessionID的时间。通过每次请求判断是否过期 (这里设置了60秒)定期生成新的ID,这样使得攻击者获取有效sessionID的机会大大降低。
73+ session启动后,我们设置了一个值,用于记录生成sessionID的时间。通过判断每次请求是否过期 (这里设置了60秒)定期生成新的ID,这样使得攻击者获取有效sessionID的机会大大降低。
6574
6675上面两个手段的组合可以在实践中消除session劫持的风险,一方面, 由于sessionID频繁改变,使攻击者难有机会获取有效的sessionID;另一方面,因为sessionID只能在cookie中传递,然后设置了httponly,所以基于URL攻击的可能性为零,同时被XSS获取sessionID也不可能。最后,由于我们还设置了MaxAge=0,这样就相当于session cookie不会留在浏览器的历史记录里面。
6776
0 commit comments