轉載:http://news.ctocio.com.cn/474/12462474_2.shtml
最近服務器也經常出現session串號的問題,於是在網上找,找到了這個,分析的在理,也順利解決了我遇到的困難。
附:技術專家對中國研究生招生信息網和新浪微博網站分析過程
1、網站基本情況:
yz.chsi.com.cn域名的唯一解析IP為 211.151.242.181;該網站其他資源文件如圖片,CSS,JS等,統一走的是 t1.chsi.com.cn至t4.chsi.com.cn 4個子域名,未使用CDN服務;該網站動態程序語言是JSP,WEB服務器是Nginx。
2、帳號管理方式:
用戶在未登錄狀態下訪問首頁,也會分配一個SESSIONID(這點和一般網站不同)。登錄后會分配一個新的SESSIONID,刷新頁面時SESSIONID不會變化。此SESSIONID是用戶的唯一標識,用戶相關信息在服務端存。
而當用戶登錄后,在請求頁面時會將此SESSIONID作為參數發放給服務端,服務端根據此ID取得用戶信息后,輸出到頁面中,頁面程序無法判別信息的真實性。
圖3:對中國研究生招生信息網的簡單分析
3、技術分析過程:
a)從用戶反饋的現象分析,原先是一個帳號,刷新頁面就變成了另一個帳號,而在這個網站上,SESSIONID是用戶身份的唯一標識,所以如果SESSIONID發生改變了,從服務端返回的帳號信息就變了(前提是另一個SESSIONID對應的用戶存在,而且處於登錄狀態)。
b)但是SESSIONID怎么會發生變化呢?有兩種可能:一種是本地的SESSIONID被篡改,一種是服務端返回的SESSIONID發生了變化。
①本地被篡改的概率相對比較小,木馬雖然存在,大多是偷盜,篡改對木馬帶不來直接的利益,而且很容易發現。
②但是按照SESSION的設定,在一次客戶端和服務端的連接中,SESSIONID是不會變化的。所以服務端返回的JSESSIONID發生變化基本上也不可能。
c)只有當用戶從未登錄變成登錄時,SESSIONID才會發生變化,但為什么會變成另一個帳號,而不是登錄的這個帳號,最大的可能性是服務端將同一個SESSIONID返回給兩個不同的用戶,那這兩個用戶就會看到同一個帳號,其中一個用戶就串號了。
①發生以上情況,不排除服務端生成SESSIONID有bug,隨機值取得不對,但這種情況發生的概率極小。目前生成SESSIONID的函數都是封裝的,java和php都有。
②如果服務端不會出錯,唯一的可能性就是客戶端和服務端中有第三者,第三者把SESSIONID弄重了。這第三者就是ISP緩存服務器。
4、 驗證結果:
a) 我們在本地構建了一個ISP緩存的模擬環境,成功重現了一個用戶帳號變成另一個用戶帳號的串號現象,並且能做到像用戶反饋的“可以直接登錄修改報名信息”。
b) 但同時串2個帳號的情況,需要在一種特別組合的情況下才出現,這個概率很小。我們仍在積極聯系反饋的用戶,驗證我們對此事情的分析。
ISP緩存的技術說明:
1、ISP緩存,本身是一種寬帶接入提供商給網頁批量訪問加速的技術。ISP會將當前訪問量較大的網頁內容放到ISP服務器的緩存中,當有新的用戶請求相同內容時,可以直接從緩存中發送相關信息,不必每次都去訪問真正的網站,從而加快了不同用戶對相同內容的訪問速度,同時也能節省網間流量結算成本。
2、ISP緩存主要以緩存靜態頁面為主,比如新浪的新聞頁。
3、 如果ISP的緩存中的網頁帶有用戶SESSIONID信息,就可能發生登錄串號現象。當用戶A登錄時服務端返回頁面內容被ISP緩存,這時同網絡的用戶B 訪問該網站,直接取得了剛才ISP緩存的信息,而該緩存信息中包含有用戶A的SESSIONID(此時用戶A還未退出),這樣用戶B處就顯示出了A的信息。
新浪微博網站分析結果如下:
1、 新浪微博的登錄驗證與weibo.com 及 sina.com.cn 兩個域名均有關聯
2、 單獨刪除任意一個域名下的COOKIE及SESSION均不影響當前登錄狀態
3、 新浪微博的登錄驗證機制比較復雜,為多冗余多關鍵字關聯生效
4、 在未能准確刪除全部關鍵KEY前提下,刪除部分會在重新刷新后自動生成
5、 目前新浪微博采用了https方式來登錄,可以避免被ISP緩存。
6、 使用目前的新浪微博登錄系統,在ISP緩存模擬環境中測試,並未重現微博串號現象。
圖4:對新浪微博頁面的簡單分析
ISP緩存導致登錄串號現象概率不高的原因:
1、 對網頁的緩存一般是小的寬帶接入提供商才采用,這種方式能提升訪問速度,節省成本,但也會有后遺症,大的寬帶接入提供商一般不敢隨便采用。
2、 同一個寬帶接入提供商下的兩個用戶,在緩存失效時間內同時登錄某一個網站時,才會出現串號,這種概率相對比較低一些。
ISP緩存導致登錄串號的解決方案:
1、 最好的解決方法是使用https來登錄,因為是通過非對稱加密,緩存設備無法得到服務器端的私鑰,所以可以避免被ISP緩存。
2、 如果覺得實施成本高,或需要快速解決,可以在請求設置SESSIONID的網頁鏈接中增加一個隨機數參數,來臨時繞過ISP緩存,但這樣可能會增加網站自身服務器的壓力,同時寬帶接入提供商也可以調整緩存策略,忽略這些隨機參數。
3、 網站也可以在SESSIONID的生成規則中加入生成IP的校驗規則,這樣至少可以確保即使SESSIONID串號了,網站自己也能發現並馬上退出登錄,從而不影響用戶隱私。
**************************************************************************************
另外也有不同的意見:(這個也是我一直在思考的,是否有這種可能,查看了Tomcat生成sessionID的源碼,不敢肯定啊,慚愧。。。)
session的id一般的是保存在cookie里面的,訪問時客戶端的id同服務器端的id相匹配。
說到微博串號的原因。我覺得有兩種可能(純屬猜測):
- 一種有可能是因為算法問題導致的id在生成的時候出現了“碰撞",這種情況一般很難遇到,但是基於微博巨大的用戶數量因而這類碰撞的產生就會有可能發生,畢竟基數太大了,難免有特例。
- 另一種,目前的服務器后台一般的都是集群處理的,有可能是在處理並行的時候沒有處理好,有可能兩台不同的服務器為不同的賬號生成了相同的id
運營商緩存了session id,有點常識確實不會這么做,不過不排除運營商緩存的bug。
我們的動態頁面就被緩存過,所以他緩存個session id,也沒什么奇怪的。
一般干這種事的,都是長城寬帶,電信通這些小運營商。