session的安全有兩層意思:web
1> 對最終客戶來講, 不會由於session的share和形成混亂, 使end-user的信息泄漏以及其餘安全問題算法
2> 對系統自己來講, 不會由於有hacker經過模擬sessionid和cookie來獲取server信任進而進行惡意破壞瀏覽器
讓咱們逐層解釋和展開問題:tomcat
1> 首先說明, 本文全部session專指Servlet HttpSession安全
2> 後臺Session和Browser之間經過JSESSIONID來關聯, JSESSIONID是Servlet標準,也是關鍵字, Servle規定Browser用Mem Cookie來存儲JSESSIONID, 注意並非disk cookie.一旦瀏覽器關閉後JSESSIONID就從PC消失, 更加安全.cookie
3> Session也是一種很好的安全認證機制, 後臺會標識session是否是已經被認證了, 若是是,就不會讓用戶再輸入password. JSESSIONID能夠被理解成爲一個已經認證的key, 因此Session有安全問題.網絡
4> Servlet容器不會構造相同的JSESSIONID, 客戶端也很難預期JSESSIONIDsession
5> HTTPS SSL等技術能夠防止網絡傳輸中有人惡意篡改JSESSIONID架構
6> 禁用Cookie的狀況JSESSIONID就必須用URLRewrite. 咱們能夠經過對URL自己採用摘要算法,自認證來防止惡意篡改JSESSIONID.app
好比: http://www.smithfox.com/abc?x=x&y=y&JSESSIONID=sdfdfsdfsdfsdfsdf&HWD=4FE23AD9892C
HWD的值是對整個URL的一個摘要算法, 若是有人改動了URL,這個HWD值就對不上了, 前提應該是這個算法別人不知道的.
7> 用戶在本身的PC上確定是能夠看到當前的JSESSIONID的, 就象就你在本身的日記中看到了本身備忘的password同樣, 這個不是技術安全問題.
8> 一臺機器有多個天然人在使用, 出現的JSESSIONID欺騙, 應該沒有技術辦法能夠解決. 只能是end-user本身當心,用完就關閉Browser. 我想這應該是在情理之中的事, 你是合租被盜應該是怪不得小區保安的, 也是須要本身平時提升防盜意識,呵呵.
9> 最近看到Tomcat7有個新的特性說是支持"防JSESSIONID劫持", 這個須要更多瞭解.
10> User和Session的關係.
Session是隻認JSESSIONID不認人的, 包括天然人和系統Account. 這個問題比較搞.
咱們用EndUser來表示天然人, User-Account表示系統賬號, 咱們分析如下幾種狀況
10.1> 兩個EndUser共用一個UserAccount而且在同一臺PC, 這個混亂不是技術問題, 你們均可以理解
10.2> 兩個EndUser分別使用不一樣的UserAccount在同一臺PC, 這個是合租狀況, 形成混亂不必定是技術問題
10.3> 某EndUser有兩個UserAccount在同一臺PC上, 咱們須要考慮JSESSIONID在client端能夠會混亂的問題.
由於不一樣的瀏覽器對於Cookie share的策略不一樣, 咱們按程序設計必須按最容易出問題的Case想,好比IE8.
不管你是IE多窗口仍是多TAB都是Share Cookie的. 因此總的指導方針是在client端作一些機制不容許用戶這麼作.
Google的gmail就是這麼作的, 你能夠一臺機器上用IE打開兩個不一樣的gmail account(兩個窗口或是兩個TAB都行),點新email或是其餘須要和後臺交互的行爲時,gmail會退出一個,提示讓你從新login而且gmail account已經固定爲後輸入的User-Account.
具體在Client怎麼防止兩個Account還需高手指點.
10.4> 某EndUserA用本身的UserAccountA先已經login,再訪問另外一個UserAccountB的資源,並且該資源是須要訪問密碼的.
這種狀況,每每由於後臺Session設計的層次不清晰,形成了UserAccountA無需Password就直接訪問到了UserAccountB的資源. 並且這個解決方案不能放在Client端, 由於訪問UserAccountB的資源可能就是一個在Email中的Link,這個click動做客戶端程序JavaScript是沒法攔截的.
10.5> 總結來講:
11> 從第10>點能夠看出, session和天然人或是UserAccount有着千絲萬縷的聯繫,但不是全部的系統只有User這一層業務概念,因此咱們須要理解後臺的Session分劃和設計好Session.Attribute層次.
咱們以一個假設業務模型爲例說明問題: 這是一個只面向企業的圖片共享web服務, 能夠爲多個公司(企業)提供服務, 用戶必須屬於某一個公司, 用戶能夠建立"圖片分組", 圖片分組能夠設置爲private(須要密碼訪問), 也能夠直接公開. 圖片分組是公司財產, user能夠建立"圖片分組", 可是圖片分組資源是歸屬公司, 同一公司內部的全部user能夠直接訪問圖片分組(若是是公開), 也能夠經過password(若是須要)訪問圖片分組.
這個業務模型中, 既有比User更高層的概念, 好比公司. 也有比User更底的概念, 好比用戶的上傳圖片分組(imageGroup).
11.1> 不一樣的war包部署在tomcat,不一樣的war包之間的session是不會混亂的, 這個是由tomcat架構決定的. 另他的沒有作過調查, 也有多是Servlet標準, 有高手能夠幫確認一下.
11.2> 多個公司又是運行在同一個tomcat application內, 怎麼防止不一樣公司之間的session混亂
能夠採用相似於防止重複提交的技術, 首先作一個優先級很高的filter, 每次reqeust和response都須要通過這個filter
在全部login模塊, 設置一個ticket cookie,寫入當前company信息, 每一個reqeust到達的第一步就是檢測client cookie和當前的URL信息, 以及session信息是否一致, 若是enduser是從一個company中click了一個其餘company的link, 該filter就會發現ticket信息不一致, 而後就強制logout, 再次讓user login. 而且每次response時作ticket的改動, 使client沒法模擬
11.3> 怎麼防止imageGroup信息混亂
Session自己是一個集合, 具體仍是使用session.attribute["key"]
Session自己是User level的, 對於低於User level的信息, 須要好好規劃attribute key
想像這樣的case:
有兩個imageGroup, 一個是public的, 一個是須要password的,
http://www.smithfox.com/companyIBM/public_images/
http://www.smithfox.com/companyIBM/password_images/
後臺對imageGroup輸入密碼邏輯的僞代碼以下:
boolean needpasswd = true;
if(session.getAttribute("NEED_PASSWORD") == null){
session.setAttribute("NEED_PASSWORD", needpasswd);
boolean needpasswd = 一個很耗時很複雜的驗證函數(user, imageGroup, xxx);
} else{
needpasswd = session.getAttribute("NEED_PASSWORD");
}
if (needpasswd ){
showPasswordDialog() ;
}
看出什麼問題沒?
應該將上面的代碼中的全部attribute key改爲 "NEED_PASSWORD"+{imageGroupID}
不然用戶只要先看了一個public後, 後面的全部圖片分組都無需passwd就能夠訪問了, 即便這個imageGroup是private的.
13> 在用session以前必定須要檢查是否真的必定須要session來解決, 好比只是想傳value到JSP page, request.setAttribte()更適合
14> 比較小而多的業務對象,若是必須save在session必定要及時removeAttribute不然session用的內存會暴漲.
由於Session不會由於客戶端不用了,就會自動清理,而是必須到SessionTimeOut纔會,若是在SessionTimeOut期間內有不少的對象在Session內,就會有問題。因此須要即時清理已經不用的Session.Attribute
15> Cookie和Session同樣, 一樣須要注意 cookie key的層次問題,以及過時問題,domain, path問題等等
分享: