1. 程式人生 > >XSS,CSRF,Cookie防劫持的處理

XSS,CSRF,Cookie防劫持的處理

而是 java php xmlhttp 無效 可能 情況下 sca 憑證

Cookie與session
HTTP天然是無狀態的協議, 為了維持和跟蹤用戶的狀態, 引入了Cookie和Session. Cookie包含了瀏覽器客戶端的用戶憑證, 相對較小. Session則維護在服務器, 用於維護相對較大的用戶信息.

用通俗的語言, Cookie是鑰匙, Session是鎖芯.

Cookie簡單理解就是鑰匙, 每次去服務端獲取資源, 需要帶著這把鑰匙, 只有自己的鎖芯(資源), 才能打開.。

但是如果鑰匙被別人拿了, 那別人就可以冒充你的身份, 去打開你的鎖芯, 從而獲取你的信息, 甚至挪用你的資金. 這是非常危險的.

XSS攻擊:
其就是利用站點開放的文本編輯並發布的功能, 從而造成攻擊,就是輸入javascript腳本, 竊取並投遞cookie信息到自己的站點.
比如攻擊者以一個普通用戶登錄進來,然後在輸入框中提交以下數據:


有了該session-id,攻擊者在會話有效期內即可獲得管理員的權限,並且由於攻擊數據已添加入數據庫,只要攻擊數據未被刪除,那麽攻擊還有可能生效,是持久性的。

Cookie的不安全就是因為這引起的。
Cookie防劫持預防
基於XSS攻擊, 竊取Cookie信息, 並冒充他人身份。
1) 方法一:
給Cookie添加HttpOnly屬性, 這種屬性設置後, 只能在http請求中傳遞, 在腳本中, document.cookie無法獲取到該Cookie值. 對XSS的攻擊, 有一定的防禦值. 但是對網絡攔截, 還是泄露了.
2)方法二:
在cookie中添加校驗信息, 這個校驗信息和當前用戶外置環境有些關系,比如ip,user agent等有關. 這樣當cookie被人劫持了, 並冒用, 但是在服務器端校驗的時候, 發現校驗值發生了變化, 因此要求重新登錄, 這樣也是種很好的思路, 去規避cookie劫持.
3)方法三:
cookie中session id的定時更換, 讓session id按一定頻率變換, 同時對用戶而言, 該操作是透明的, 這樣保證了服務體驗的一致性.

用大白話談談XSS與CSRF

CSRF攻擊是源於WEB的隱式身份驗證機制!WEB的身份驗證機制雖然可以保證一個請求是來自於某個用戶的瀏覽器,但卻無法保證該請求是用戶批準發送的!

如何防禦?
請求令牌(一種簡單有效的防禦方法):
首先服務器端要以某種策略生成隨機字符串,作為令牌(token),保存在 Session 裏。然後在發出請求的頁面,把該令牌以隱藏域一類的形式,與其他信息一並發出。在接收請求的頁面,把接收到的信息中的令牌與 Session 中的令牌比較,只有一致的時候才處理請求,處理完成後清理session中的值,否則返回 HTTP 403 拒絕請求或者要求用戶重新登陸驗證身份
令牌來防止 CSRF 有以下幾點要註意:
a.雖然請求令牌原理和驗證碼有相似之處,但不應該像驗證碼一樣,全局使用一個 Session Key。因為請求令牌的方法在理論上是可破解的,破解方式是解析來源頁面的文本,獲取令牌內容。如果全局使用一個 Session Key,那麽危險系數會上升。原則上來說,每個頁面的請求令牌都應該放在獨立的 Session Key 中。我們在設計服務器端的時候,可以稍加封裝,編寫一個令牌工具包,將頁面的標識作為 Session 中保存令牌的鍵。

b.在 ajax 技術應用較多的場合,因為很有請求是 JavaScript 發起的,使用靜態的模版輸出令牌值或多或少有些不方便。但無論如何,請不要提供直接獲取令牌值的 API。這麽做無疑是鎖上了大門,卻又把鑰匙放在門口,讓我們的請求令牌退化為同步令牌。

c.第一點說了請求令牌理論上是可破解的,所以非常重要的場合,應該考慮使用驗證碼(令牌的一種升級,目前來看破解難度極大),或者要求用戶再次輸入密碼(亞馬遜、淘寶的做法)。但這兩種方式用戶體驗都不好,所以需要產品開發者權衡。

d.無論是普通的請求令牌還是驗證碼,服務器端驗證過一定記得銷毀。忘記銷毀用過的令牌是個很低級但是殺傷力很大的錯誤。我們學校的選課系統就有這個問題,驗證碼用完並未銷毀,故只要獲取一次驗證碼圖片,其中的驗證碼可以在多次請求中使用(只要不再次刷新驗證碼圖片),一直用到。

如下也列出一些據說能有效防範 CSRF,其實效果甚微或甚至無效的做法:
a.通過 referer 判定來源頁面:referer 是在 HTTP Request Head 裏面的,也就是由請求的發送者決定的。如果我喜歡,可以給 referer 任何值。當然這個做法並不是毫無作用,起碼可以防小白。但我覺得性價比不如令牌。

b.過濾所有用戶發布的鏈接:這個是最無效的做法,因為首先攻擊者不一定要從站內發起請求(上面提到過了),而且就算從站內發起請求,途徑也遠遠不知鏈接一條。比如 <img src="./create_post.php" /> 就是個不錯的選擇,還不需要用戶去點擊,只要用戶的瀏覽器會自動加載圖片,就會自動發起請求。

c.在請求發起頁面用 alert 彈窗提醒用戶:這個方法看上去能幹擾站外通過 iframe 發起的 CSRF,但攻擊者也可以考慮用 window.alert = function(){}; 把 alert 弄啞,或者幹脆脫離 iframe,使用 Flash 來達到目的。

總體來說,目前防禦 CSRF 的諸多方法還沒幾個能徹底無解的。 作為開發者,我們能做的就是盡量提高破解難度。當破解難度達到一定程度,網站就逼近於絕對安全的位置了。

安全防範

CSRF(Cross-site request forgery,跨站請求偽造),是通過偽造請求,冒充用戶在站內進行操作

比如,點擊發帖後會進行如下GET請求

http://example.com/bbs/create_post.php?title=標題&content=內容

那麽,如果我們模擬了請求的鏈接,那麽只要有用戶點擊了這個鏈接,他就會在不知情的情況下發布了這一帖子,那麽刪貼,發郵件等等都可以進行偽造

http://example.com/bbs/create_post.php?title=攻擊&content=哈哈

如何防範 CSRF 攻擊

  • CSRF 攻擊之所以能夠成功:是因為黑客可以完全偽造用戶的請求,該請求中所有的用戶驗證信息都是存在於 cookie 中,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的 cookie 來通過安全驗證
  • 所以解決辦法是:在請求中放入黑客所不能偽造的信息,並且該信息不存在於 cookie 之中
  • 驗證 HTTP Referer 字段
  • 關鍵操作只接受POST請求,因為GET請求的參數攜帶在URL中,很容易進行模擬,而POST請求的參數在http body中
  • 驗證碼,每次操作都需要用戶進行互動,從而簡單有效的防禦了CSRF攻擊,但是驗證碼太多,也會影響用戶體驗
  • 可以在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端來驗證這個 token
  • 可以在 HTTP 頭中自定義的屬性裏加入一個隨機產生的 token,通過XMLHttpRequest,可以給所有請求加上這個token,通過XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄,也不用擔心 token 會透過 Referer 泄露到其他網站中

註意:過濾用戶輸入的內容不能阻擋 CSRF,我們需要做的是過濾請求的來源

XSS(Cross Site Scripting,跨站腳本攻擊),是註入攻擊的一種,特點是不對服務器端造成任何傷害,而是通過一些正常的站內交互途徑

例如:發布評論,提交含有 JavaScript 的內容文本,如果服務器端沒有過濾或轉義掉這些腳本,作為內容發布到了頁面上,其他用戶訪問這個頁面的時候就會運行這些腳本,或者是一些未授權的操作

while (true) { alert("你關不掉我~"); }

在輸入框中輸入document.cookie,可以直接獲得cookie中的內容,所以,在重要的cookie參數中加入httpOnly屬性

XSS 是實現 CSRF 的諸多途徑中的一條,一般習慣上把通過 XSS 來實現的 CSRF 稱為 XSRF

如何防禦 XSS 攻擊

理論上,所有可輸入的地方沒有對輸入數據進行處理的話,都會存在XSS漏洞,防禦 XSS 攻擊最簡單直接的方法,就是過濾用戶的輸入

可以直接對用戶的輸入進行 HTML escape

<script>window.location.href=”http://www.baidu.com”;</script>

經過 escape 之後,就不能執行了

 <script>window.location.href="http://www.baidu.com"</script> 

XSS,CSRF,Cookie防劫持的處理