日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Web应用安全————Shiro 解决会话固定漏洞

發(fā)布時(shí)間:2025/3/12 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Web应用安全————Shiro 解决会话固定漏洞 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

引言

承接上一篇《Web應(yīng)用安全————賬號(hào)凍結(jié)與 Session 實(shí)時(shí)失效》關(guān)于 session 的學(xué)習(xí),本篇博客聚焦如何通過 shiro 解決會(huì)話固定導(dǎo)致的漏洞問題。

首先,沒怎么接觸過應(yīng)用安全方面的小伙伴可能會(huì)發(fā)起疑問 - 什么是會(huì)話固定?

簡(jiǎn)單來說,系統(tǒng)在登錄前和登錄后使用同一個(gè) session id,就是會(huì)話固定,默認(rèn)的session 管理機(jī)制都是會(huì)話固定的。會(huì)話固定可能會(huì)造成“會(huì)話固定攻擊”(Session Fixation Attack)。這種攻擊形式簡(jiǎn)單來說,有幾種:

1、黑客先訪問一個(gè)目標(biāo)網(wǎng)站,在未登錄的情況下,獲得了一個(gè) session id,然后將這個(gè) session id 以釣魚郵件的形式發(fā)給某個(gè)該網(wǎng)站的用戶,用戶缺乏信息安全意識(shí),點(diǎn)擊郵件中帶有 session id 的連接并登錄成功后,根據(jù)“會(huì)話固定”的登錄前和登錄后 session id 保持不變的原理,黑客可以在一定時(shí)間內(nèi)使用 這個(gè) session id 繞過登錄驗(yàn)證,操作該用戶的個(gè)人賬戶。

2、黑客通過某種形式的網(wǎng)絡(luò)抓包,在某個(gè)用戶登錄時(shí),劫持到了 session id,待該用戶登錄成功后,根據(jù)“會(huì)話固定”的原理,黑客可以在一定時(shí)間內(nèi)通過這個(gè) session id 隨意操作該用戶的個(gè)人賬戶。

一、會(huì)話固定攻擊演示

固定會(huì)話攻擊實(shí)際上就是黑客通過某種方式獲得了正常用戶登錄時(shí)的 session id,然后利用用戶的登錄操作,使 session id 生效,并繞過登錄驗(yàn)證。由于在登錄前,session id 會(huì)通過 cookie 保存到瀏覽器中,因此很容易被黑客竊取。

1、首先,普通用戶打開登錄頁面,會(huì)獲得一個(gè)由服務(wù)器響應(yīng)攜帶而來的 session id cookie:

在瀏覽器的控制臺(tái),我們可以輕而易舉的得到這個(gè) session id,此時(shí),由于還未登錄,session id 是無法正常使用的,黑客通過某種方式,比如腳本,或者桌面監(jiān)控等,獲取到了這個(gè) session id ,放入自己準(zhǔn)備登錄的工具中。這里我使用post man 來演示黑客端的登錄操作。

2、黑客輸入目標(biāo)網(wǎng)站的首頁地址,這時(shí),應(yīng)用會(huì)攔截請(qǐng)求并彈出登錄頁面,此時(shí)黑客同樣會(huì)收到服務(wù)器返回的 session id,不過他不會(huì)使用這個(gè) session id,而是將竊取來的 session id 拷貝到 cookie 中,等待用戶的登錄操作

3、緊接著,用戶不知道自己的 session id 已經(jīng)被竊取,依然執(zhí)行了登錄操作,并成功登錄:

4、此時(shí),黑客使用這個(gè)已經(jīng)完成登錄操作的 session id 再次執(zhí)行首頁的訪問:

可以看到上面的 GIF,黑客僅僅是使用了一個(gè) session id 就完成了對(duì)用戶首頁的訪問,輕而易舉地繞過了登錄驗(yàn)證。如果這個(gè)用戶是超級(jí)管理員,那么就可能對(duì)系統(tǒng)造成不小的傷害。

因此,為了解決這個(gè)會(huì)話固定的問題,必須在登錄前和登錄后刷新 session id ,并使登錄前生成 的session 失效,這樣,才不會(huì)讓黑客利用會(huì)話固定繞過登錄驗(yàn)證。

二、Shiro 防止會(huì)話固定

如果說上一篇文章可以是框架無關(guān)的操作,那么解決會(huì)話固定,就完全依賴于安全框架自身的一些封裝方式。

在Shiro 中, session 的生成和保存是這樣的:

1、shiro 檢測(cè)到用戶的請(qǐng)求,并生成 session,保存到緩存中 ,并將 session id 綁定在 response 的 cookie 中,響應(yīng)回瀏覽器?。

2、用戶攜帶 session id,完成登錄操作后,服務(wù)器端就會(huì)更新 session 的狀態(tài),并將其 綁定到 Subject 中。

在登錄前的 session 生成時(shí),session 還不知道它要綁定到哪個(gè)用戶上,僅僅是生成了一個(gè)標(biāo)記了主機(jī)地址的SimpleSession 對(duì)象。當(dāng)用戶調(diào)用 shiro 的登錄驗(yàn)證方法 login()的時(shí)候,完成正常的驗(yàn)證操作,Shiro 就會(huì)將這個(gè) session 綁定到當(dāng)前用戶 Subject 中。

public void login(AuthenticationToken token) throws AuthenticationException {Subject subject = securityManager.login(this, token);......Session session = subject.getSession(false);if (session != null) {this.session = decorate(session);} else {this.session = null;} }

因此,我的解決思路就是,在完成 login 方法后,注銷掉當(dāng)前的 session ,并重新獲得一個(gè) 新的session ,綁定到 Subject 中。

/** * 點(diǎn)擊登錄執(zhí)行的動(dòng)作 */ @RequestMapping(value = "/login", method = RequestMethod.POST) public String loginVali() {// ...... 從request 中獲取 username 和 passwordSubject currentUser = ShiroKit.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(username, password.toCharArray());......currentUser.login(token);// 創(chuàng)建新的session 會(huì)話,并管理 shiro session idsessionProcessor.shiroSessionIdIntoPool();// Session 重置后,重新調(diào)用login()方法,其內(nèi)部自動(dòng)捆綁新的 session 到當(dāng)前SubjectcurrentUser.login(token);return REDIRECT + "/"; }

這里我單獨(dú)提取了一個(gè)方法,來完成這一操作:?

注意,getSession() 方法需要我們傳入一個(gè)參數(shù),默認(rèn)是 true,意思是,如果這個(gè)用戶還沒有session ,就為其創(chuàng)建一個(gè)新的 session,如果是false,那么就不為其創(chuàng)建。上圖的紅框內(nèi),我們首先獲得了當(dāng)前登錄用戶的 session 對(duì)象,并調(diào)用了 stop 方法,將其注銷,再為用戶生成 一個(gè) 新的 session 對(duì)象。其他的部分,主要是為了維護(hù)一個(gè) session id 池,將用戶名與 session id的對(duì)應(yīng)關(guān)系保存在 一個(gè) map 中,方便管理員用戶找到其他用戶的 session id,并執(zhí)行相關(guān)操作。

注意,在生成新的 session 后,必須重復(fù)調(diào)用一下 login 方法,將其再次綁定到當(dāng)前用戶中

三、測(cè)試結(jié)果演示

用戶打開登錄界面,依然會(huì)獲得一個(gè)服務(wù)端返回的 session id :

黑客竊取到這個(gè) session id ,并拷貝到自己的登陸工具中(演示使用的是Post Man):

用戶輸入用戶名和密碼,登錄到首頁后,可以看到,雖然地址欄中使用了舊的 session id 完成登錄操作,但是cookie 中的已經(jīng)變成了新的 session id ,并為接下來的請(qǐng)求提供了新的 session :

此時(shí),如果黑客使用舊的 session id 再次執(zhí)行登錄,就無法成功(請(qǐng)對(duì)比修改前的效果):

由此可見,我們?cè)诖a中刷新了 session 的操作已經(jīng)成功。

總結(jié)

解決會(huì)話固定實(shí)際上就是在登錄后,通過代碼實(shí)現(xiàn) session 的刷新(重新生成),保證登錄前后使用不同的 session id 即可。雖然新的 session id 依然有可能被黑客竊取,但相對(duì)于固定的 session id ,也算在一定程度上提升了系統(tǒng)的安全性。

在解決會(huì)話固定的時(shí)候,我考慮了很多問題。

最初并不了解會(huì)話固定需要解決的最關(guān)鍵問題是什么,誤以為只需要將用戶過去的 session 注銷即可,實(shí)則不然。導(dǎo)致這個(gè)想法的原因是由于我發(fā)現(xiàn),當(dāng)用戶沒有安全退出,而是直接關(guān)閉瀏覽器后,服務(wù)器端的 session 無法主動(dòng)注銷,需要等待到超時(shí)時(shí)間后,再執(zhí)行注銷操作。因此在 session 的處理方法中,我在用戶 登錄之后,先根據(jù)用戶名 找到他上次沒有注銷,且未超時(shí)的 session ,并將其注銷。但這還不是“會(huì)話固定”。

后來我了解到了會(huì)話固定實(shí)際上是登錄前后擁有相同的 session id ,才意識(shí)到,注銷以前使用過的 session 并沒有真正解決了 session 會(huì)話固定的問題。

于是我開始思考在 Shiro 中如何創(chuàng)建新的 session,我本以為需要繼承 DefaultSessionManager 或其子類并重寫doCreateSession(SessionContext context) 方法,然后代替DefaultWebSessionManager 裝載到 SecurityManager 中,但我發(fā)現(xiàn)?SessionContext 好像很難從請(qǐng)求中 手動(dòng)構(gòu)造出來(需要重寫好幾層繼承關(guān)系的邏輯鏈),把整個(gè) session 的創(chuàng)建過程和保存過程梳理了好幾遍,都沒找到很好的切入點(diǎn),最后,還是通過 Subject 的 getSession 方法 發(fā)現(xiàn)了可執(zhí)行的方案。

注銷掉原來的 session 并通過 getSession(true) 方法成功刷新了 session 之后,我又發(fā)現(xiàn),在重定向的時(shí)候,會(huì)導(dǎo)致系統(tǒng)找不到用戶請(qǐng)求中的 session id,也就是說,我新生成的 session ,用戶并沒有成功接收到它的 session id。于是我又開始思考如何將 session id 放入 cookie 中返回給瀏覽器。但實(shí)際上,并不是如此,在生成session 的時(shí)候,SessionManager就已經(jīng)將 session id 放入到了 response 的 cookie 中。

其實(shí)是用戶和新生成的 session 并沒有形成綁定,于是我又開始研究 Shiro 的 login()方法究竟做了哪些工作,這才發(fā)現(xiàn),login 實(shí)際上在驗(yàn)證完成用戶之后,會(huì)把已經(jīng)生成的 session 綁定 到當(dāng)前 Subject 上,于是,這才有了兩次調(diào)用 login() 的操作。

currentUser.login(token);// 創(chuàng)建新的session 會(huì)話,并管理 shiro session idsessionProcessor.shiroSessionIdIntoPool();// Session 重置后,重新調(diào)用login()方法,其內(nèi)部自動(dòng)捆綁新的 session 到當(dāng)前SubjectcurrentUser.login(token);

雖然實(shí)際修改的代碼就只有兩三行,但不得不說,會(huì)話固定的修改過程真是充滿了挑戰(zhàn),前后一刻不停整整花了2大天時(shí)間。不過,通過自己的思考和努力解決一個(gè)問題真的非常有成就感。

綜上,就是通過 Shiro 解決會(huì)話固定問題的全過程,歡迎大家文末留言。

總結(jié)

以上是生活随笔為你收集整理的Web应用安全————Shiro 解决会话固定漏洞的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。