How can I password-protect my /sidekiq route (i.e. require authentication for the Sidekiq::Web tool)?

我怕爱的太早我们不能终老 提交于 2019-12-03 06:11:49

问题


I am using sidekiq in my rails application. By Default, Sidekiq can be accessed by anybody by appending "/sidekiq" after the url. I want to password protect / authenticate only the sidekiq part. How can i do that?


回答1:


Put the following into your sidekiq initializer

require 'sidekiq'
require 'sidekiq/web'

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

And in the routes file:

authenticate :user do
  mount Sidekiq::Web => '/sidekiq'
end



回答2:


See "Security" under https://github.com/mperham/sidekiq/wiki/Monitoring

Sidekiq::Web uses Rack::Protection to protect your application against typical web attacks (such as CSRF, XSS, etc). Rack::Protection would invalidate your session and raise Forbidden error if it finds that your request doesn't satisfy security requirements. One of the possible situations is having your application working behind a reverse proxy and not passing important headers to it (X-Forwarded-For,X-Forwarded-Proto). Such situation and solution could be found in this article and issue #2560...




回答3:


Sorry to late to the party, but Sidekiq's wiki recommends the following for Devise:

To allow any authenticated User:

# config/routes.rb
authenticate :user do
  mount Sidekiq::Web => '/sidekiq'
end

To restrict access to User.admin?

# config/routes.rb
authenticate :user, lambda { |u| u.admin? } do
  mount Sidekiq::Web => '/sidekiq'
end

This wiki post also has many other security schemes.

This was tested using Rails 5.1.3, Devise 4.3 and Sidekiq 5.0




回答4:


If you're using Devise (or other Warden-based authentication), you can do this, supposing you have an AdminUser model in your app.

# 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



回答5:


If you are rolling your own custom authentication, then you can use the below example which is referenced in the docs here.

# 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



回答6:


Another option would be to add something like CanCan and special access based on roles.




回答7:


If you're using Sorcery for authentication, here's how to use Rails routes constraints to protect certain routes.


Copied here from the sorcery wiki for redundancy:

This tutorial shows how to use Rails routes constraints with Sorcery gem. Thanks to @anthonator for writing it!

First, define UserConstraint module that will be used for all constraints:

module RouteConstraints::UserConstraint
  def current_user(request)
    User.find_by_id(request.session[:user_id])
  end
end

Then, having that module defined, you can specify specific constraint classes. In these examples, first route will work only if there's no user logged in, the second will work only for logged user who is an admin:

class RouteConstraints::NoUserRequiredConstraint
  include RouteConstraints::UserConstraint

  def matches?(request)
    !current_user(request).present?
  end
end

class RouteConstraints::AdminRequiredConstraint
  include RouteConstraints::UserConstraint

  def matches?(request)
    user = current_user(request)
    user.present? && user.is_admin?
  end
end

Finally, you can add the constraints to the config/routes.rb:

MyApp::Application.routes.draw do

  # other routes …

  root :to => 'admin#dashboard', :constraints => RouteConstraints::AdminRequiredConstraint.new
  root :to => 'home#welcome', :constraints => RouteConstraints::NoUserRequiredConstraint.new

end



回答8:


The accepted answer is good, but I think that it can be implemented more securely, as Sidekiq documentation mentions.

To protect your app against timing attacks, use ActiveSupport::SecurityUtils.secure_compare.

  • See https://codahale.com/a-lesson-in-timing-attacks/
  • See https://thisdata.com/blog/timing-attacks-against-string-comparison/

Also, use & (do not use &&) so that it doesn't short circuit.

And finally, use digests to stop length information leaking (default of secure_compare in Active Support 5).

Active Support 5: Thanks to Rails PR #24510, parameters passed to secure_compare are going through Digest::SHA256.hexdigest by default.

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

Active Support 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


来源:https://stackoverflow.com/questions/12265421/how-can-i-password-protect-my-sidekiq-route-i-e-require-authentication-for-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!