2012-02-20 37 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