Sinatra/1.4.3使用Rack::Session::Cookie警告

12

我的配置代码

require 'sinatra'

#set :environment, :production
enable :sessions
enable :logging
set run: true

case
  when production?
    set port: 8081
  when development?
    require 'sinatra/reloader'
    require 'better_errors'
    use BetterErrors::Middleware
    BetterErrors.application_root = __dir__
end

use Rack::Session::Cookie, key: 'N&wedhSDF',
    domain: "localhost",
    path: '/',
    expire_after: 14400,
    secret: '*&(^B234'

get '/' do
  erb :hello
end

它仍然显示警告:

SECURITY WARNING: No secret option provided to Rack::Session::Cookie.
This poses a security threat. It is strongly recommended that you
provide a secret to prevent exploits that may be possible from crafted
cookies. This will not be supported in future versions of Rack, and
future versions will even invalidate your existing user cookies.

但它在生产环境中没有显示出来

问题是,如果Rack::Session::Cookie已经设置,为什么仍然会显示警告?

1个回答

37

您正在同时使用两种方法

enable :sessions

这个使Sinatra设置基于cookie的会话,并且

use Rack::Session::Cookie, ...

这也会向你的应用程序添加会话,因此您最终在中间件堆栈中有两个Rack::Session::Cookie实例。

警告是由Sinatra包含的会话中间件生成的。默认情况下,在开发环境中运行时,Sinatra 不会创建会话密钥(至少在经典模式下不会,在模块化应用程序中会),因此Rack会在开发过程中生成警告。

您只需要使用其中一种启用会话的方法即可,同时使用两种方法可能会导致它们以意外的方式相互交互。

为了避免警告,您可以使用session_secret选项显式设置Sinatra会话的密钥:

enable :sessions
set :session_secret, '*&(^B234'

您还可以在启用会话时将选项哈希作为参数传递。不使用 enable :sessions,而是这样做:

set :sessions, key: 'N&wedhSDF',
  domain: "localhost",
  path: '/',
  expire_after: 14400,
  secret: '*&(^B234'

你能解释一下设置session_secret的作用吗?我一直在寻找答案,但是无论如何都找不到。我最好的猜测是它将其用作哈希的盐,以防止人们伪造cookie。 - Piccolo
@Piccolo 是的,它是为了防止人们伪造cookie,但它被用作HMAC中的密钥,而不是盐。查看Rack cookie session code以获取更多信息。 - matt
非常感谢!我正在研究它。还有,是否有任何原因我不能在应用程序开始时生成新的秘密密钥? - Piccolo
@Piccolo,我非常确定这样做的后果是每次重新启动应用程序时,会销毁会话,因此人们必须重新登录...还有其他可能存储在会话中的东西。 - counterbeing
我的问题是关于同时使用两种方式启用会话。谢谢你找出来了! - ifyouseewendy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接