2012-02-20 49 views
8

我需要在Rails中的一個cookie中存儲一小段數據(少於10個字符),並且我需要它是安全的。我不希望任何人能夠讀取這些數據或注入他們自己的數據(因爲這會打開應用程序以應對各種攻擊)。我認爲加密cookie的內容是一種方式(我是否也應該簽名?)。什麼是最好的方式來做到這一點?使用Rails存儲加密的cookie

現在我正在做這個,看起來很安全,但對於那些比我更瞭解安全性的人來說,很多東西看起來都很安全,然後發現它並不安全。

我節省這樣的祕密:

encryptor = ActiveSupport::MessageEncryptor.new(Example::Application.config.secret_token) 
cookies[:secret] = { 
    :value => encryptor.encrypt(secret), 
    :domain => "example.com", 
    :secure => !(Rails.env.test? || Rails.env.development?) 
} 

,然後我讀這樣的:

encryptor = ActiveSupport::MessageEncryptor.new(Example::Application.config.secret_token) 
secret = encryptor.decrypt(cookies[:secret]) 

是不是安全的?任何更好的方法來做到這一點?

更新:我知道Rails的會話,以及它如何是安全的,由雙方簽署的cookie,並通過可選存儲會話服務器端的內容,我使用的會話它是什麼。但我的問題在於存儲Cookie,這是我不想在會話中提供的一條信息,但我仍然需要它是安全的。

+0

出於興趣,它爲什麼需要存儲在cookie中而不是服務器端,它在定義上更安全? – Russell 2012-02-20 16:56:55

+0

@russell很好,你需要在瀏覽器中存儲一些東西,對吧?否則你將無法再識別它。無論是實際數據還是表格中記錄的標識,這都是關於數據大小和其他考慮因素的首選和必要問題。我存儲的內容已經是表格中記錄的標識。我可以創建另一張桌子,但在這種情況下看起來很浪費。 – Pablo 2012-02-20 17:14:36

+0

我已經添加了一個答案,因爲我認爲更改默認會話存儲以使用數據庫會給你想要的安全性,只需很少的開銷就創建表等。 – Russell 2012-02-20 23:35:12

回答

0

我正在重新發布JacobM的答案,他刪除了,因爲這是正確的答案,並指出我在正確的方向。如果他沒有刪除它,我會刪除這個並選擇他作爲最佳答案。

首先,如果你使用的encrypt_and_verify代替encrypt將 籤餅。

但是,當涉及到安全問題時,我總是傾向於依靠已公開審查的解決方案,而不是自己動手。 一個例子是encrypted-cookies gem

+0

我很好奇你爲什麼不使用已簽名的cookies?(默認情況下支持Rails 3.x) – 2012-02-22 20:05:07

+1

@KandadaBoggu由encrypt_and_verify或encrypted-cookies gem(post 1.0)處理的cookie已簽名,但也是加密的。如果這部分數據暴露出來,這並不是那麼嚴重,但我寧願不考慮它,只是通過加密來保證它的安全,因此對用戶來說是不透明的。 – Pablo 2012-02-23 10:50:42

+0

這很有道理.. – 2012-02-23 11:46:27

13
  • 設置安全cookie

    cookies.signed[:secret] = { 
    :value => "foo bar", 
    :domain => "example.com", 
    :secure => !(Rails.env.test? || Rails.env.development?) 
    } 
    
  • 訪問餅乾

    cookies.signed[:secret] # returns "foo bar" 
    

該Cookie使用ActionController::Base.cookie_verifier_secret簽名。您可以在初始化文件中設置cookie_verifier_secret

+0

我不想使用會話。我的會話是每個域(blah.example.com),而這段數據是針對整個系統(.example.com)的,因此在設置域時是域選項。 – Pablo 2012-02-21 10:01:33

+0

更新了答案看看。 – 2012-02-21 16:16:40

+0

使用.signed設置的Cookie也需要使用.signed進行訪問。所以你的第二個代碼塊應該是'cookies.signed [:secret]'。 – 2012-09-07 21:01:08

1

正如KandadaBoggu所說,它看起來像你想要的是一個會話變量,並且會話變量默認被加密並存儲在cookie中。但是,如果你看看在config/initializers/session_store.rb的內容,你會發現類似如下:

# Be sure to restart your server when you modify this file. 
MyRailsApp::Application.config.session_store :cookie_store, :key => '_my_rails_app_session' 

# Use the database for sessions instead of the cookie-based default, 
# which shouldn't be used to store highly confidential information 
# (create the session table with "rails generate session_migration") 
# MyRailsApp::Application.config.session_store :active_record_store 

這表明,我認爲你應該使用數據庫會話,而不是基於cookie的默認情況下,該不該」用於存儲高度機密的信息。預先安裝的遷移使一切都非常容易設置,所以這樣做的開銷很小,一旦完成,基本上沒有任何開銷,如果您需要在以後添加新的祕密信息!

+0

我不想使用會話。我的會話是每個域(blah.example.com),而這段數據是針對整個系統(.example.com)的,因此在設置域時是域選項。 – Pablo 2012-02-21 10:01:28