session劫持是一種廣泛存在的比較嚴重的安全威脅,在session技術中,客戶端和服務端通過session的識別符號來維護會話, 但這個識別符號很容易就能被嗅探到,從而被其他人利用.它是中間人攻擊的一種型別,
本節將通過一個實體來演示會話劫持,希望通過這個實體,能讓讀者更好地理解session的本質,
session劫持程序
我們寫了如下的代碼來展示一個count計數器:
func count(w http.ResponseWriter, r *http.Request) {
sess := globalSessions.SessionStart(w, r)
ct := sess.Get("countnum")
if ct == nil {
sess.Set("countnum", 1)
} else {
sess.Set("countnum", (ct.(int) + 1))
}
t, _ := template.ParseFiles("count.gtpl")
w.Header().Set("Content-Type", "text/html")
t.Execute(w, sess.Get("countnum"))
}
count.gtpl的代碼如下所示:
Hi. Now count:{{.}}
session劫持防范
cookieonly和token
通過上面session劫持的簡單演示可以了解到session一旦被其他人劫持,就非常危險,劫持者可以假裝成被劫持者進行很多非法操作,那么如何有效的防止session劫持呢?
其中一個解決方案就是sessionID的值只允許cookie設定,而不是通過URL重置方式設定,同時設定cookie的httponly為true,這個屬性是設定是否可通過客戶端腳本訪問這個設定的cookie,第一這個可以防止這個cookie被XSS讀取從而引起session劫持,第二cookie設定不會像URL重置方式那么容易獲取sessionID,
第二步就是在每個請求里面加上token,實作類似前面章節里面講的防止form重復遞交類似的功能,我們在每個請求里面加上一個隱藏的token,然后每次驗證這個token,從而保證用戶的請求都是唯一性,
h := md5.New()
salt:="astaxie%^7&8888"
io.WriteString(h,salt+time.Now().String())
token:=fmt.Sprintf("%x",h.Sum(nil))
if r.Form["token"]!=token{
//提示登錄
}
sess.Set("token",token)
間隔生成新的SID
還有一個解決方案就是,我們給session額外設定一個創建時間的值,一旦過了一定的時間,我們銷毀這個sessionID,重新生成新的session,這樣可以一定程度上防止session劫持的問題,
createtime := sess.Get("createtime")
if createtime == nil {
sess.Set("createtime", time.Now().Unix())
} else if (createtime.(int64) + 60) < (time.Now().Unix()) {
globalSessions.SessionDestroy(w, r)
sess = globalSessions.SessionStart(w, r)
}
session啟動后,我們設定了一個值,用于記錄生成sessionID的時間,通過判斷每次請求是否過期(這里設定了60秒)定期生成新的ID,這樣使得攻擊者獲取有效sessionID的機會大大降低,
上面兩個手段的組合可以在實踐中消除session劫持的風險,一方面, 由于sessionID頻繁改變,使攻擊者難有機會獲取有效的sessionID;另一方面,因為sessionID只能在cookie中傳遞,然后設定了httponly,所以基于URL攻擊的可能性為零,同時被XSS獲取sessionID也不可能,最后,由于我們還設定了MaxAge=0,這樣就相當于session cookie不會留在瀏覽器的歷史記錄里面,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/258362.html
標籤:其他
下一篇:用戶注冊密碼加密和后端校驗的權衡
