Skip to content

Commit

Permalink
Fix CSRF vulnerability reported by Egor Homakov, fixes sidekiq#2422
Browse files Browse the repository at this point in the history
  • Loading branch information
mperham committed Jul 6, 2015
1 parent 777392a commit cf3c43b
Show file tree
Hide file tree
Showing 14 changed files with 42 additions and 2 deletions.
9 changes: 8 additions & 1 deletion Changes.md
@@ -1,7 +1,14 @@
HEAD
3.4.2
-----------

- Safer display of job data in Web UI [#2405]
- Fix CSRF vulenerability in Web UI, thanks to Egor Homakov for
reporting. [#2422] If you are running the Web UI as a standalone Rack app,
ensure you have a [session middleware
configured](https://github.com/mperham/sidekiq/wiki/Monitoring#standalone):
```ruby
use Rack::Session::Cookie, :secret => "some unique secret string here"
```

3.4.1
-----------
Expand Down
2 changes: 1 addition & 1 deletion lib/sidekiq/version.rb
@@ -1,3 +1,3 @@
module Sidekiq
VERSION = "3.4.1"
VERSION = "3.4.2"
end
2 changes: 2 additions & 0 deletions lib/sidekiq/web.rb
Expand Up @@ -11,6 +11,8 @@ module Sidekiq
class Web < Sinatra::Base
include Sidekiq::Paginator

use Rack::Protection, :use => :authenticity_token unless ENV['RACK_ENV'] == 'test'

set :root, File.expand_path(File.dirname(__FILE__) + "/../../web")
set :public_folder, proc { "#{root}/assets" }
set :views, proc { "#{root}/views" }
Expand Down
4 changes: 4 additions & 0 deletions lib/sidekiq/web_helpers.rb
Expand Up @@ -173,6 +173,10 @@ def display_args(args, truncate_after_chars = 2000)
end.join(", ")
end

def tkn
session[:csrf]
end

def to_display(arg)
begin
arg.inspect
Expand Down
13 changes: 13 additions & 0 deletions myapp/simple.ru
@@ -0,0 +1,13 @@
# Easiest way to run Sidekiq::Web.
# Run with "bundle exec rackup simple.ru"

require 'sidekiq'

# A Web process always runs as client, no need to configure server
Sidekiq.configure_client do |config|
config.redis = { url: 'redis://localhost:6379/0', size: 1 }
end

require 'sidekiq/web'
use Rack::Session::Cookie, :secret => "some unique secret string here"
run Sidekiq::Web
2 changes: 2 additions & 0 deletions web/views/busy.erb
Expand Up @@ -4,6 +4,7 @@
</div>
<div class="col-sm-4 pull-right">
<form method="POST" style="margin-top: 20px; margin-bottom: 10px;">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<div class="btn-group pull-right">
<button class="btn btn-warn" type="submit" name="quiet" value="1"><%= t('QuietAll') %></button>
<button class="btn btn-danger" type="submit" name="stop" value="1"><%= t('StopAll') %></button>
Expand Down Expand Up @@ -40,6 +41,7 @@
<td>
<div class="btn-group pull-right">
<form method="POST">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<input type="hidden" name="identity" value="<%= process['identity'] %>"/>
<button class="btn btn-warn" type="submit" name="quiet" value="1"><%= t('Quiet') %></button>
<button class="btn btn-danger" type="submit" name="stop" value="1"><%= t('Stop') %></button>
Expand Down
1 change: 1 addition & 0 deletions web/views/dead.erb
Expand Up @@ -27,6 +27,7 @@
</div>

<form class="form-horizontal" action="<%= root_path %>morgue/<%= job_params(@dead, @dead.score) %>" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<a class="btn btn-default" href="<%= root_path %>morgue"><%= t('GoBack') %></a>
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
Expand Down
3 changes: 3 additions & 0 deletions web/views/morgue.erb
Expand Up @@ -12,6 +12,7 @@

<% if @dead.size > 0 %>
<form action="<%= root_path %>morgue" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<div class="table_container">
<table class="table table-striped table-bordered table-white">
<thead>
Expand Down Expand Up @@ -57,9 +58,11 @@
</form>

<form action="<%= root_path %>morgue/all/delete" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
</form>
<form action="<%= root_path %>morgue/all/retry" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
</form>

Expand Down
1 change: 1 addition & 0 deletions web/views/queue.erb
Expand Up @@ -33,6 +33,7 @@
</td>
<td>
<form action="<%= root_path %>queues/<%= @name %>/delete" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<input name="key_val" value="<%= h Sidekiq.dump_json(msg.item) %>" type="hidden" />
<input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSure') %>" />
</form>
Expand Down
1 change: 1 addition & 0 deletions web/views/queues.erb
Expand Up @@ -18,6 +18,7 @@
<td><%= number_with_delimiter(queue.size) %> </td>
<td width="20%">
<form action="<%=root_path %>queues/<%= queue.name %>" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSureDeleteQueue', :queue => h(queue.name)) %>" />
</form>
</td>
Expand Down
3 changes: 3 additions & 0 deletions web/views/retries.erb
Expand Up @@ -12,6 +12,7 @@

<% if @retries.size > 0 %>
<form action="<%= root_path %>retries" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<div class="table_container">
<table class="table table-striped table-bordered table-white">
<thead>
Expand Down Expand Up @@ -60,9 +61,11 @@
</form>

<form action="<%= root_path %>retries/all/delete" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
</form>
<form action="<%= root_path %>retries/all/retry" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
</form>

Expand Down
1 change: 1 addition & 0 deletions web/views/retry.erb
Expand Up @@ -27,6 +27,7 @@
</div>

<form class="form-horizontal" action="<%= root_path %>retries/<%= job_params(@retry, @retry.score) %>" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<a class="btn btn-default" href="<%= root_path %>retries"><%= t('GoBack') %></a>
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
Expand Down
1 change: 1 addition & 0 deletions web/views/scheduled.erb
Expand Up @@ -13,6 +13,7 @@
<% if @scheduled.size > 0 %>

<form action="<%= root_path %>scheduled" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<div class="table_container">
<table class="table table-striped table-bordered table-white">
<thead>
Expand Down
1 change: 1 addition & 0 deletions web/views/scheduled_job_info.erb
@@ -1,6 +1,7 @@
<%= erb :_job_info, :locals => {:job => @job, :type => :scheduled} %>

<form class="form-horizontal" action="<%= root_path %>scheduled/<%= job_params(@job, @job.score) %>" method="post">
<input type="hidden" name="authenticity_token" value="<%= tkn %>"/>
<a class="btn btn-default" href="<%= root_path %>scheduled"><%= t('GoBack') %></a>
<input class="btn btn-primary" type="submit" name="add_to_queue" value="<%= t('AddToQueue') %>" />
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
Expand Down

0 comments on commit cf3c43b

Please sign in to comment.