Cross Site Request Forgery 簡稱 CSRF 是網路上最常見的攻擊方式,由於前端的盛行,現在開發網站偏向前後端拆開,前端使用大量的 Javascript 及 CSS3 效果,後端則是使用 PHP, Ruby, Python… 等,前端如何拿到資料庫資料呢,必需透 過 AJAX 方式來存取,常見的後端 API 會設計成 RESTful (GET/PUT/POST/DELETE),後端為了擋住 CSRF 攻擊,所以限定了特殊 Content-Type Header,前端需要帶 application/json 給後端才可以拿到資料,這只能透過 Ajax requests 才可以做到。
但是很不幸的是使用者還是透過 header injection 方式來達到目的 (Flash exploits),所以透過判斷 Content-Type Header 這方式是不夠的。正確的防護方式就是在每個 request 給上一組 token,因為 same origin policy 關係,攻擊者無法拿到此 token,無法達到攻擊效果。 如果你是 Ruby 愛好者,可以透過
Rack CSRF 來產生 token,並且放在網頁 Head 內
在 jQuery 部份,必須使用 ajaxPrefilter 將每個 Request 加上 CSRF token 傳給伺服器var CSRF_HEADER = 'X-CSRF-Token'; var setCSRFToken = function(securityToken) { jQuery.ajaxPrefilter(function(options, _, xhr) { if ( !xhr.crossDomain ) xhr.setRequestHeader(CSRF_HEADER, securityToken); }); }; setCSRFToken($('meta[name="csrf-token"]').attr('content'));如果是在 Head 內加上 csrf-token 就必須透過上述作法,但是
CodeIgniter 並非是使用此方式,要將 CSRF 打開可以透過 config/config.php 內的
$config['csrf_protection'] = FALSE; $config['csrf_token_name'] = 'csrf-token'; $config['csrf_cookie_name'] = 'csrf-token'; $config['csrf_expire'] = 7200;將 csrf_protection 改成 true,這樣透過 from helper 產生的 form 表單,你會發現會多出 hidden input value,這樣送出表單的時候就可以驗證此 token 是否正確,如果你不是透過 CI form 表單產生,那也可以在 Client 端抓取 csrf-token 的 Cookie 資料,因為 CI 也會同時將 csrf-token value 寫入 Cookie,Cookie 可以透過
jQuery cookie plugin 來讀取。 另外如果你也想透過最上面 head 方式來處理,CI 那邊也可以透過 $this->security->get_csrf_hash() 來取 hash 資料,將此資料放到 html head 裡面即可。
See also
- CodeIgniter 3.0 Release 終於釋出啦
- Ruby Deploy With Capistrano 碰到 SSH Connection Closed
- CodeIgniter 搭配 Homestead 開發環境
- CodeIgniter 終於找到新東家 British Columbia Institute of Technology 英屬哥倫比亞理工學院
- 實戰 CodeIgniter in 成功大學計算機與網路中心
- 升級 PHP Facebook SDK 到 4.0.x 版本
- Using Capistrano to deploy current branch
- Ruby Compass and Sass Auto Testing Environment
- Ruby 安裝 debugger package 發生 No source for ruby 錯誤
- 在 Ubuntu 或 Debian 上跑 Ruby on Rails + Nginx