如何密码保护我的/ sidekiq路由(即需要对Sidekiq :: Web工具进行身份验证)?

sag*_*kar 53 ruby rescue redis ruby-on-rails-3 sidekiq

我在rails应用程序中使用sidekiq.默认情况下,任何人都可以通过在网址后附加"/ sidekiq"来访问Sidekiq.我想密码保护/验证sidekiq部分.我怎样才能做到这一点?

小智 95

将以下内容放入sidekiq初始化程序中

require 'sidekiq'
require 'sidekiq/web'

Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
  [user, password] == ["sidekiqadmin", "yourpassword"]
end
Run Code Online (Sandbox Code Playgroud)

并在路线文件中:

authenticate :user do
  mount Sidekiq::Web => '/sidekiq'
end
Run Code Online (Sandbox Code Playgroud)

  • 您不需要“身份验证”块。如果您不使用设计,它会在 rails 6 上给出错误 (5认同)
  • BTW-I在我的Gemfile中添加了以下内容,因此我不必在初始化程序和routes.rb文件中手动要求sidekiq和sidekiq/web:"gem'sidekiq',require:['sidekiq','sidekiq /网络']" (3认同)
  • 至少在我运行 Rails 5 的应用程序中,我没有必要用 `authenticate` 块包装 `mount` 调用。 (3认同)
  • 如 Sidekiq 项目中所述,您可能想要使用`ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(user), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_USER"])) & ActiveSupport ::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_PASSWORD"]))` 来比较用户名和密码。 (2认同)
  • 警告!使用 `==` 运算符会将应用程序暴露给计时攻击。任何攻击者都可以通过根据请求处理时间一个一个地猜测每个字符,最终找出密码是什么。使用`ActiveSupport::SecurityUtils.secure_compare`、`Devise.secure_compare` 等。 (2认同)

Mar*_*dig 14

请参阅https://github.com/mperham/sidekiq/wiki/Monitoring下的"安全性"

Sidekiq :: Web使用Rack :: Protection来保护您的应用程序免受典型的Web攻击(例如CSRF,XSS等).Rack :: Protection会使您的会话无效,Forbidden如果发现您的请求不满足安全要求,则会引发错误.其中一种可能的情况是让您的应用程序在反向代理之后工作,而不是将重要的标头传递给它(X-Forwarded-For,X-Forwarded-Proto).这种情况和解决方案可以在本文问题#2560中找到 ......


Tom*_*nda 13

很抱歉迟到了派对,但Sidekiq的维基推荐以下版本的Devise:

允许任何经过身份验证User:

# config/routes.rb
authenticate :user do
  mount Sidekiq::Web => '/sidekiq'
end
Run Code Online (Sandbox Code Playgroud)

限制访问 User.admin?

# config/routes.rb
authenticate :user, lambda { |u| u.admin? } do
  mount Sidekiq::Web => '/sidekiq'
end
Run Code Online (Sandbox Code Playgroud)

这个wiki帖子还有许多其他安全方案.

这是使用Rails 5.1.3,Devise 4.3和Sidekiq 5.0测试的


小智 10

如果您正在使用Devise(或其他基于Warden的身份验证),则可以执行此操作,假设您的应用程序中有AdminUser模型.

# config/routes.rb
# This defines the authentication constraint
constraint = lambda do |request|
               request.env['warden'].authenticate!({ scope: :admin_user })
             end

# This mounts the route using the constraint.
# You could use any other path to make it less obvious
constraints constraint do
  mount Sidekiq::Web => '/sidekiq'
end
Run Code Online (Sandbox Code Playgroud)


jam*_*iii 7

如果您正在滚动自己的自定义身份验证,则可以使用此处文档中引用的以下示例.

# lib/admin_constraint.rb
class AdminConstraint
  def matches?(request)
    return false unless request.session[:user_id]
    user = User.find request.session[:user_id]
    user && user.admin?
  end
end

# config/routes.rb
require 'sidekiq/web'
require 'admin_constraint'
mount Sidekiq::Web => '/sidekiq', :constraints => AdminConstraint.new
Run Code Online (Sandbox Code Playgroud)


Cap*_*pot 7

接受的答案很好,但我认为它可以更安全地实现,正如Sidekiq 文档提到的 那样(在我发布后对其进行了编辑以演示正确的解决方案)。

为了保护您的应用程序免受计时攻击,请使用ActiveSupport::SecurityUtils.secure_compare.

另外,使用&(请勿使用&&)以免短路。

最后,使用摘要来阻止长度信息泄漏(secure_compareActive Support 5 中的默认设置)。

因此,在初始化程序文件中(通常在config/initializers/sidekiq.rbRails 项目中),根据您的 Active Support/Rails 版本,编写以下内容。

主动支持 5+:感谢Rails PR #24510secure_compare ,默认情况下传递给的参数Digest::SHA256.hexdigest

require 'active_support/security_utils'
require 'sidekiq'
require 'sidekiq/web'

Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
  # Protect against timing attacks:
  # - See https://codahale.com/a-lesson-in-timing-attacks/
  # - See https://thisdata.com/blog/timing-attacks-against-string-comparison/
  # - Use & (do not use &&) so that it doesn't short circuit.
  # - Use digests to stop length information leaking
  ActiveSupport::SecurityUtils.secure_compare(user, ENV["SIDEKIQ_ADMIN_USER"]) &
    ActiveSupport::SecurityUtils.secure_compare(password, ENV["SIDEKIQ_ADMIN_PASSWORD"])
end
Run Code Online (Sandbox Code Playgroud)

积极支持4

require 'active_support/security_utils'
require 'sidekiq'
require 'sidekiq/web'

Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
  # Protect against timing attacks:
  # - See https://codahale.com/a-lesson-in-timing-attacks/
  # - See https://thisdata.com/blog/timing-attacks-against-string-comparison/
  # - Use & (do not use &&) so that it doesn't short circuit.
  # - Use digests to stop length information leaking
  ActiveSupport::SecurityUtils.secure_compare(
    ::Digest::SHA256.hexdigest(user),
    ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_ADMIN_USER"])
  ) &
    ActiveSupport::SecurityUtils.secure_compare(
      ::Digest::SHA256.hexdigest(password),
      ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_ADMIN_PASSWORD"])
    )
end
Run Code Online (Sandbox Code Playgroud)