瀏覽器的安全缺陷
現在的Web應用程式幾乎都是使用Cookie來識別使用者身份以及儲存工作階段狀態,但是所有的瀏覽器在最初加入Cookie功能時並沒有考慮安全因素,從 WEB頁面產生的檔案請求都會帶上COOKIE,如下圖所示,Web頁面中的一個正常的圖片所產生的請求也會帶上COOKIE:
<img src=”yun_qi_img/logo.jpg”>
GET yun_qi_img/log.jpg
Cookie: session_id
用戶端 ——————————————————-伺服器
咱們按照這個思路,山寨一個crumb的實現,代碼如下:
代碼如下 |
複製代碼 |
<?php class Crumb { CONST SALT = "your-secret-salt"; static $ttl = 7200; static public function challenge($data) { return hash_hmac('md5', $data, self::SALT); } static public function issueCrumb($uid, $action = -1) { $i = ceil(time() / self::$ttl); return substr(self::challenge($i . $action . $uid), -12, 10); } static public function verifyCrumb($uid, $crumb, $action = -1) { $i = ceil(time() / self::$ttl); if(substr(self::challenge($i . $action . $uid), -12, 10) == $crumb || substr(self::challenge(($i - 1) . $action . $uid), -12, 10) == $crumb) return true; return false; } } |
代碼中的$uid表示使用者唯一標識,而$ttl表示這個隨機串的有效時間。
應用樣本
在表單中插入一個隱藏的隨機串crumb
代碼如下 |
複製代碼 |
<form method="post" action="demo.php"> <input type="hidden" name="crumb" value="<?php echo Crumb::issueCrumb($uid)?>"> <input type="text" name="content"> <input type="submit"> </form> |
處理表單 demo.php
對crumb進行檢查
代碼如下 |
複製代碼 |
<?php if(Crumb::verifyCrumb($uid, $_POST['crumb'])) { //按照正常流程處理表單 } else { //crumb校正失敗,錯誤提示流程 } |
注意:
CSRF攻擊和相關web蠕蟲的爆發,並且針對這類web攻擊制定有效應急措施。同建議程式員不要濫用$_REQUEST類變數,在必要的情況下給某些敏感的操作加上浮水印,考慮使用類似DISCUZ論壇的formhash技術提高駭客預測請求參數的難度,注意JSON資料介面的安全問題等