我特別接受POST
前驗證用戶的會話。如果你的意思是「會話」通常意味着:存儲在識別用戶的cookie中的持久令牌和相關聯的會話數據,那麼不,這還不夠。即使POST請求被另一個(攻擊者)站點激發,該cookie也會被瀏覽器自動發送。
您在這裏尋找的關鍵字是跨站點請求僞造或XSRF,其中經過身份驗證的用戶可以由攻擊者(通過腳本或其他方法)向您的站點發出GET或POST請求。這些請求通常不會與合法請求區分開來。 (有些人通過檢查HTTP引用數據嘗試這樣做,但這是不可靠的。)
這些攻擊不像服務器端(SQL,命令)或客戶端(HTML,JavaScript)那樣立即造成損害,注射,但它們比兩者更普遍:不幸的是,很少有網絡程序員都採用適當的對策。直到他們的網站被XSRF漏洞攻陷。
有多種方法可以抵禦XSRF,但唯一真正有效的方法是在每個提交表單中包含第三方攻擊者不會知道的祕密值。正如Eimantas所提到的,這通常被稱爲郵政鑰匙。
有多種方式可以產生這樣的祕密信息。一種簡單的方法是爲每個用戶的帳戶詳細信息添加一個隨機生成的代碼,然後將其放在表單的隱藏字段中,並檢查其在提交中的存在。例如在PHP中:
<form method="post" action="delete.php"><div>
<input type="hidden" name="key" value="<?php echo(htmlspecialchars($user['key'])); ?>"/>
<input type="submit" value="Delete" />
</div></form>
if ($_POST['key']!=$user['key'])
// error
攻擊者不會知道該用戶的密鑰,因此無法創建包含該密鑰的鏈接/表單。
您也可以在服務器密鑰上對用戶的ID使用加密哈希函數,而不是保留單獨的代碼。使用散列,您還可以投入其他內容,例如到期時間,以便表單必須在特定時間範圍內提交。或者,您可以生成一次性交易密鑰,您也可以使用它來確保無法兩次提交相同的表單(用於停止重複發佈)。
+1表示「安全性必須在服務器上執行」。這不能說得太多。 – 2009-09-13 13:39:52