CodeIgniter開啟CSRF保護時使用Ajax

最近在利用CodeIgniter開發網站時,需要檢查使用者輸入的值是否有重複,為了避免使用者都輸入完資料送出表單後才去檢查,利用JQuery中的Ajax在輸入完的時候就進行檢查,但是利用Chrome Developer Tool來Debug時候,發現錯誤訊息是:

POST http://localhost/index.php/my_ajax/is_username_duplicate 500 (Internal Server Error)

最後Google後發現原來是我在之前開啟CSRF的問題。

一、什麼是CSRF

CSRF(Cross-Site Request Forgey, 跨站冒名請求)為當使用者在已登入的狀態下,被攻擊的人執行了使用者未知的操作,因為,當使用者在登入狀態下,只要不關閉瀏覽器,就會保留著Session或Cookie,網站通常都是利用檢查Session或Cookie來確認使否連線進來的使用者是否已經登入,所以攻擊者可以利用社交攻擊,傳送一個連結或操作等,使用者在未知情況下去操作,就可能會依照使用者所安排好的操作去執行,聽來聽去可能有點霧煞煞,參考網路上的一下範例解釋一下:

HTTP Request有兩種分別是POST及GET,在GET 方法可以利用網址後面帶入變數的方式,例如:

攻擊者可能利用電子郵件或者社群網站寄送一個連結給使用者

http://www.buy.com/buy.php?item=002&to=attack

這個連結可能是讓使用者買某個東西送給某人,如果使用者不經意點擊,就可能發生了,那會有人說改用POST就好了,其實不盡然,因為只要攻擊者利用JavaScript就可以執行POST 方法了

二、CSRF解決方法

參考OWASP的文件,利用同步Token方式解決,可以在執行POST及GET動作時,都去檢查隨機產生出來的Token值是否正確,像Codeigniter就是利用在form中帶入Token值,到接收值的Controller中必須檢查Token值是否一致,當然檢查步驟跟產生都是Codeigniter做好的,這個方法可以避免當受到跨站攻擊時,攻擊者不知道Token值,而沒辦法讓使用者進行未知操作。

三、Codeigniter中的CSRF Protection

在Codeigniter中的CSRF 保護可以利用設定config.php開啟,在application/config/config.php中

只要將$config[‘csrf_protection’]設定為TRUE即可,那表單的部分要加入Token值該如何加入呢?其實,Codeigniter都做好了,只要在View中利用form_open(),form_open()就會自己產生出隱藏欄位,所以當submit時候就會把Token 值給帶過去接收的function了。

產生出的HTML

<div style=”display:none”>
<input type=”hidden” name=”aming_csrf” value=”f3d2b8571036872e780afcf46060328a” />
</div>

四、解決Ajax與CSRF Protection

了解CSRF Protection的機制後,就可以了解Ajax POST的問題了,就是需要在Ajax 中帶入Token值

我們利用$(‘input[name=aming_csrf]’).val() 得到Token 值,然後在Ajax POST中加入對應的CSRF參數名稱與值,在接收POST的function就會去驗證Token 值是否正確了。

參考資料

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) OWASP
http://aymsystems.com/ajax-csrf-protection-codeigniter-20/ AYM Systems

CodeIgniter開啟CSRF保護時使用Ajax

對「CodeIgniter開啟CSRF保護時使用Ajax」的想法

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料