我一直在尋找方法來防止會話劫持,其中有人竊取會話cookie並使用它來訪問系統。使用時間戳防止會話劫持?
諸如http://codebutler.com/firesheep之類的程序可以輕鬆地在開放式無線網絡上嗅探會話,其他獲取會話的方式包括跨站點腳本攻擊,或者只是將其從受害者的計算機上提取出來。
使用SSL來保護所有會話cookie /服務器通信對於防止Firesheep嗅探至關重要,並且在cookie上設置HTTPOnly有助於防止JavaScript在XSS攻擊中讀取會話cookie,但它仍然容易受到AJAX基於攻擊。
另一層是爲包括安全令牌或在會話cookie即得到對每個請求更新隨機數。將令牌存儲在服務器端數據存儲區和Cookie中,並且在比較每個請求時,Cookie中的令牌與數據存儲區中的令牌相匹配。
如果令牌不匹配,可能是某人偷走會話並嘗試使用它的指示符,因此您可以忽略請求或使會話無效並要求用戶重新進行身份驗證。但是,不匹配的標記也可能是由於緩慢/片狀連接造成的。
例如,你可以有當服務器收到來自真實用戶的請求,服務器數據存儲更新會話令牌和響應與包含更新的令牌的會話cookie的用戶的情況下。但是由於緩慢/片狀的連接,用戶沒有收到響應,所以用戶仍舊擁有舊的會話令牌,而新的會話令牌存儲在服務器上。當用戶重試請求時,令牌將不匹配。
緩解這個問題的一種方法是讓服務器保留最後幾個令牌的歷史記錄,並檢查它們是否匹配,然後它變成需要保留多少令牌的情況,並且取決於片狀連接是或如何使用戶點擊快樂,服務器可以在連接回來之前循環瀏覽歷史記錄,並且瀏覽器更新用戶的會話。
到保持令牌歷史另一種方法是時間戳每個會話,並檢查時間戳是一些短,規定的範圍內,例如30秒。如果用戶的會話cookie時間戳記在服務器存儲的會話時間戳記的30秒內,則會話視爲可信。
例僞
def authenticate_request():
if (stored_session.timestamp - session.timestamp > 30 seconds):
return False
return True
這避免了保持令牌歷史 - 時間戳記令牌 - 但攻擊者有機會就偷了之後劫持會話30秒的窗口。雖然這是真的,但令牌歷史選擇並不是更好,因爲它給攻擊者一個潛在的更長時間的機會。
檢查IP地址和用戶代理變化的其他方法也有問題。用戶代理很容易被欺騙,如果攻擊者能夠獲得用戶的會話,他們可以通過相同的XSS代碼或其他方式輕鬆確定用戶代理。
如果用戶在移動設備上,它們的IP地址可能會經常發生變化,這樣會導致許多誤報。此外,攻擊者可能位於同一公司防火牆之後,因此用戶和攻擊者的IP與外部Web服務器的IP相同。
是使用時間戳令牌正確的做法還是有更好的辦法? 30秒的緩衝區是否正確?我缺少哪些優勢案例?
它不需要他們每30秒重新加載一次頁面 - 它們可以在任何時間內消失。重要的是會話中的時間戳與下一個請求中存儲在服務器上的時間戳相匹配。 – espeed 2011-06-16 21:19:28
是的,任何未被確認的數據都可能被攔截和複製,但除非他們攔截了用戶最後一次請求的會話,否則令牌/時間戳將在用戶的下一個請求中更新,因此攔截的令牌無效。唯一有效的是他們能夠在用戶上一次請求的30秒窗口內攔截並使用它。 – espeed 2011-06-16 21:27:19
我想我不明白你的時間戳代表什麼時間,以及你在比較它。我只是重讀你的原始文章,你說「時間戳每個會話」。但是什麼時候?它創建時?當你最後發送一個頁面給用戶?等等。無論如何,你說這個時間戳會被髮送回服務器。但是,任何嗅探該線路的人都可以看到會話ID和時間戳。我沒有看到你獲得了什麼。無論如何,我認爲你需要澄清一下你所做的更多。 – Jay 2011-06-17 19:54:54