Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic auth for /sidekiq in Rails API only project #4061

Closed
NicoSa opened this issue Dec 19, 2018 · 9 comments
Closed

Basic auth for /sidekiq in Rails API only project #4061

NicoSa opened this issue Dec 19, 2018 · 9 comments

Comments

@NicoSa
Copy link

NicoSa commented Dec 19, 2018

Ruby version: ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin17]
Rails version: 5.2.1.1
Sidekiq / Pro / Enterprise version(s): 5.2.3 free version

We are running a brand new Rails project as an api only project with devise.

Now I added Sidekiq and I realised that it is actually not that easy to add basic auth to it in this case. We'd be fine with just basic auth for the endpoint (/sidekiq) as well. However since our app and therefore devise does not have a UI, how would I sign in? That is also why using this wont work:

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

Does anyone have any suggestions on how we could cleanly add Basic Auth on the /sidekiq endpoint in an api only rails project?

@mperham
Copy link
Collaborator

mperham commented Dec 19, 2018 via email

@NicoSa
Copy link
Author

NicoSa commented Dec 19, 2018

Thanks. Throwing away Devise is not an option ;)

Searching for it on the rack level was a good hint though! Found something and this works:

require 'sidekiq/web'

Sidekiq::Web.use Rack::Auth::Basic do |username, password|
    username == 'some_user' && password == 'some_password'
end
mount Sidekiq::Web => '/sidekiq'

@NicoSa NicoSa closed this as completed Dec 19, 2018
@chrishough
Copy link

chrishough commented May 17, 2020

Thank you for posting this @NicoSa = I have updated this slightly.

Sidekiq::Web.use(Rack::Auth::Basic) do |username, password|
  username == Rails.application.credentials[Rails.env.to_sym][:sidekiqweb][:username] &&
    password == Rails.application.credentials[Rails.env.to_sym][:sidekiqweb][:password]
end

mount(Sidekiq::Web => "/#{Time.now.strftime("%Y%m%d")}sidekiqadmin")

@Nowaker
Copy link
Contributor

Nowaker commented Nov 7, 2020

@chrishough Don't use == for password comparison. Use ActiveSupport::SecurityUtils.secure_compare(p1, p2), or timing attack can be used to find out what the password is.

@chrishough
Copy link

thank you @Nowaker

@mbronek7
Copy link

@Nowaker based on
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/security_utils.rb
I think values that are passed to secure_compare need to be of the same length and already been processed by HMAC.
So probably this would be the correct way to compare this passwords:

 ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username), ::Digest::SHA256.hexdigest(Rails.application.credentials[Rails.env.to_sym][:sidekiqweb][:username])) &
 ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest(Rails.application.credentials[Rails.env.to_sym][:sidekiqweb][:password]))

also I think that we should use & instead of && to evaluate two expressions instead of one if left fails.
https://wiki.sei.cmu.edu/confluence/display/java/EXP54-J.+Understand+the+differences+between+bitwise+and+logical+operators

@Nowaker
Copy link
Contributor

Nowaker commented Nov 24, 2020

@mbronek7 They need to be the same length for fixed_length_secure_compare only. It's not a case for secure_compare which is intended to be used as simply as ActiveSupport::SecurityUtils.secure_compare(p1, p2).

But you're right about &.

@mbronek7
Copy link

mbronek7 commented Nov 24, 2020

@Nowaker yes you're right forgive me I looked at fixed_length_secure_compare and thought about secure_compare, thank you.

Oh and they changed this recently and it is not in current version od documentation
rails/rails@3261e41#diff-e60ac5ff67c9b37c5105c77cf480113c16ad4613f80d2096a41fedff41e4b0dc
sorry once again

@chrishough
Copy link

In case others come across this post, here is my latest variation for this:

  Sidekiq::Web.use(Rack::Auth::Basic) do |username, password|
    ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username), ::Digest::SHA256.hexdigest(Rails.application.credentials.dig(:sidekiqweb, :username))) &
      ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest(Rails.application.credentials.dig(:sidekiqweb, :password)))
  end

  mount(Sidekiq::Web => "/sidekiqadmin")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants