RailsアプリケーションでSidekiqを使用しています。デフォルトでは、誰でもSidekiqにアクセスできます。URLの後に「/ sidekiq」を追加します。それをしてもいいですか?
以下をsidekiqイニシャライザーに入れます
require 'sidekiq'
require 'sidekiq/web'
Sidekiq::Web.use(Rack::Auth::Basic) do |user, password|
[user, password] == ["sidekiqadmin", "yourpassword"]
end
そして、routesファイルで:
authenticate :user do
mount Sidekiq::Web => '/sidekiq'
end
https://github.com/mperham/sidekiq/wiki/Monitoring の「セキュリティ」を参照してください
Sidekiq :: Webは Rack :: Protection を使用して、典型的なWeb攻撃からアプリケーションを保護します( [〜#〜] csrf [〜#〜] 、 など) [〜#〜] xss [〜#〜] など)。 Rack :: Protectionは、リクエストがセキュリティ要件を満たさないと判断した場合、セッションを無効にし、
Forbidden
エラーを発生させます。考えられる状況の1つは、アプリケーションをリバースプロキシの背後で動作させ、重要なヘッダーを渡さないことです(X-Forwarded-For
、X-Forwarded-Proto
)。このような状況と解決策を見つけることができました この記事 および issue#256 ...
パーティーに遅れてすみませんが、 Sidekiqのwiki はDeviseに以下を推奨しています:
認証されたUser
を許可するには:
# config/routes.rb
authenticate :user do
mount Sidekiq::Web => '/sidekiq'
end
User.admin?
へのアクセスを制限するには
# config/routes.rb
authenticate :user, lambda { |u| u.admin? } do
mount Sidekiq::Web => '/sidekiq'
end
このwiki投稿 には他にも多くのセキュリティスキームがあります。
これは、Rails 5.1.3、Devise 4.3およびSidekiq 5.0を使用してテストされました
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
独自のカスタム認証を展開している場合、ドキュメントで参照されている以下の例を使用できます 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
別のオプションは、CanCanのようなものと、役割に基づいた特別なアクセスを追加することです。
認証に Sorcery を使用している場合、ここに Rails特定のルートを保護するためのルート制約 。
冗長性のためにソーサリーwikiからここにコピーしました。
このチュートリアルでは、Sorcery gemでRails routes制約を使用する方法を示します。作成に @ anthonator に感謝します!
最初に、すべての制約に使用されるUserConstraint
モジュールを定義します。
module RouteConstraints::UserConstraint
def current_user(request)
User.find_by_id(request.session[:user_id])
end
end
次に、そのモジュールを定義したら、特定の制約クラスを指定できます。これらの例では、最初のルートはログインしているユーザーがいない場合にのみ機能し、2番目は管理者であるログインしているユーザーに対してのみ機能します。
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
最後に、制約を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
受け入れられた答えは良いですが、 Sidekiqドキュメントの言及 のように、より安全に実装できると思います。
アプリをタイミング攻撃から保護するには、ActiveSupport::SecurityUtils.secure_compare
。
また、&
(使ってはいけません &&
)短絡しないように。
最後に、ダイジェストを使用して、長さの情報の漏洩を防ぎます(デフォルトはsecure_compare
in Active Support 5)。
アクティブサポート5: Rails PR#2451 のおかげで、secure_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
アクティブサポート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