diff --git a/lib/sidekiq/web/csrf_protection.rb b/lib/sidekiq/web/csrf_protection.rb index 58d55b67..24b54904 100644 --- a/lib/sidekiq/web/csrf_protection.rb +++ b/lib/sidekiq/web/csrf_protection.rb @@ -90,6 +90,11 @@ module Sidekiq end sess = session(env) + + # Checks that Rack::Session::Cookie did not return empty session + # object in case the digest verification failed + return false if sess.empty? + localtoken = sess[:csrf] # Rotate the session token after every use diff --git a/test/test_csrf.rb b/test/test_csrf.rb index 16f517f5..adc9b182 100644 --- a/test/test_csrf.rb +++ b/test/test_csrf.rb @@ -6,11 +6,11 @@ class TestCsrf < Minitest::Test @session ||= {} end - def env(method=:get, form_hash={}) + def env(method=:get, form_hash={}, rack_session=session) imp = StringIO.new("") { "REQUEST_METHOD" => method.to_s.upcase, - "rack.session" => session, + "rack.session" => rack_session, "rack.logger" => ::Logger.new(@logio ||= StringIO.new("")), "rack.input" => imp, "rack.request.form_input" => imp, @@ -59,7 +59,6 @@ class TestCsrf < Minitest::Test end def test_good_and_bad_posts - goodtoken = nil # Make a GET to set up the session with a good token goodtoken = call(env) do |envy| envy[:csrf_token] @@ -82,4 +81,20 @@ class TestCsrf < Minitest::Test assert_equal 403, result[0] assert_equal ["Forbidden"], result[2] end + + def test_empty_session_post + # Make a GET to set up the session with a good token + goodtoken = call(env) do |envy| + envy[:csrf_token] + end + assert goodtoken + + # Make a POST with an empty session data and good token + result = call(env(:post, { "authenticity_token" => goodtoken }, {})) do + raise "shouldnt be called" + end + refute_nil result + assert_equal 403, result[0] + assert_equal ["Forbidden"], result[2] + end end