2011-02-15 73 views
20

當CSRF令牌不匹配時,Rails引發InvalidAuthenticityToken。但是,從閱讀source,我無法弄清楚這是如何發生的。我從acking那棵樹開始:Rails CSRF保護如何工作?

$ ack --ignore-dir=test InvalidAuthenticityToken 

actionpack/lib/action_controller/metal/request_forgery_protection.rb 
4: class InvalidAuthenticityToken < ActionControllerError #:nodoc: 
17: # which will check the token and raise an ActionController::InvalidAuthenticityToken 

actionpack/lib/action_dispatch/middleware/show_exceptions.rb 
22:  'ActionController::InvalidAuthenticityToken' => :unprocessable_entity 

只有兩個命中,忽略註釋。第一個是類定義:

class InvalidAuthenticityToken < ActionControllerError #:nodoc: 
end 

第二個是將異常轉換爲HTTP狀態代碼。 CSRF保護得到由控制器調用protect_from_forgery啓用,所以讓我們看看:

def protect_from_forgery(options = {}) 
    self.request_forgery_protection_token ||= :authenticity_token 
    before_filter :verify_authenticity_token, options 
end 

它增加了一個過濾器:

def verify_authenticity_token 
    verified_request? || handle_unverified_request 
end 

當驗證失敗調用該:

def handle_unverified_request 
    reset_session 
end 

那麼InvalidAuthenticityToken實際上是如何提升的?

回答

21

行爲是changed fairly recently但文檔尚未更新。正在使用的新方法是假定會話已被劫持,因此要清除會話。假設你的會話包含這個請求的所有重要的認證信息(例如你登錄爲alice的事實),並且你的控制器保證用戶通過了這個動作的認證,你的請求將被重定向到一個登錄頁面(或者你選擇處理未登錄的用戶)。但是,對於未通過身份驗證的請求(如註冊表單),請求將使用空會話。

看來這個提交也繼續關閉CSRF vulnerability,但我沒有讀到細節。

爲了得到舊的行爲,你會簡單地定義這個方法:

def handle_unverified_request 
    raise(ActionController::InvalidAuthenticityToken) 
end 

你可以閱讀更多關於CSRF等Rails的安全問題在Ruby on Rails Security Guide

+0

謝謝!這就是我運行3.0.3但讀取master的源代碼所得到的結果。對這一變化背後原因的很好解釋 - 甚至比官方博客文章中的更好。 – 2011-02-15 23:45:22

9

verify_authenticity_token曾經被定義爲

verified_request? || raise(ActionController::InvalidAuthenticityToken) 

但正如你提到的,現在叫handle_unverified_request,進而調用reset_session

我不認爲Rails的實際拋出的異常了。

http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails狀態

應用這個補丁失敗後CSRF 請求將不再生成HTTP 500錯誤,而不是會議將 復位。用戶可以通過在其自己的 控制器中重寫 handle_unverified_request來覆蓋此行爲。

https://github.com/rails/rails/commit/66ce3843d32e9f2ac3b1da20067af53019bbb034

+0

謝謝!我希望我能接受這兩個答案。 – 2011-02-15 23:48:04