diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 93e05225b20..2ec9882e3a3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -159,6 +159,10 @@ class ApplicationController < ActionController::Base end rescue_from Discourse::InvalidAccess do |e| + + if e.opts[:delete_cookie].present? + cookies.delete(e.opts[:delete_cookie]) + end rescue_discourse_actions( :invalid_access, 403, diff --git a/lib/auth/default_current_user_provider.rb b/lib/auth/default_current_user_provider.rb index 8c56dc9d5af..c46ee178b33 100644 --- a/lib/auth/default_current_user_provider.rb +++ b/lib/auth/default_current_user_provider.rb @@ -48,7 +48,7 @@ class Auth::DefaultCurrentUserProvider if auth_token && auth_token.length == 32 limiter = RateLimiter.new(nil, "cookie_auth_#{request.ip}", COOKIE_ATTEMPTS_PER_MIN , 60) - if request.ip == "127.0.0.1" || request.ip == "::1" || limiter.can_perform? + if limiter.can_perform? @user_token = UserAuthToken.lookup(auth_token, seen: true, user_agent: @env['HTTP_USER_AGENT'], @@ -62,7 +62,11 @@ class Auth::DefaultCurrentUserProvider begin limiter.performed! rescue RateLimiter::LimitExceeded - raise Discourse::InvalidAccess + raise Discourse::InvalidAccess.new( + 'Invalid Access', + nil, + delete_cookie: TOKEN_COOKIE + ) end end end diff --git a/lib/discourse.rb b/lib/discourse.rb index 4a558224c69..036836c6057 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -64,12 +64,12 @@ module Discourse # When they don't have permission to do something class InvalidAccess < StandardError - attr_reader :obj, :custom_message + attr_reader :obj, :custom_message, :opts def initialize(msg = nil, obj = nil, opts = nil) super(msg) - opts ||= {} - @custom_message = opts[:custom_message] if opts[:custom_message] + @opts = opts || {} + @custom_message = opts[:custom_message] if @opts[:custom_message] @obj = obj end end diff --git a/spec/integration/rate_limiting_spec.rb b/spec/integration/rate_limiting_spec.rb index b51439c1e8e..b1cc23afce8 100644 --- a/spec/integration/rate_limiting_spec.rb +++ b/spec/integration/rate_limiting_spec.rb @@ -2,16 +2,29 @@ require 'rails_helper' -describe 'admin rate limit' do +describe 'rate limiter integration' do before do RateLimiter.enable + RateLimiter.clear_all! end after do RateLimiter.disable end + it "will clear the token cookie if invalid" do + name = Auth::DefaultCurrentUserProvider::TOKEN_COOKIE + + # we try 11 times because the rate limit is 10 + 11.times { + cookies[name] = SecureRandom.hex + get '/categories.json' + expect(response.cookies.has_key?(name)).to eq(true) + expect(response.cookies[name]).to be_nil + } + end + it 'can cleanly limit requests' do #request.set_header("action_dispatch.show_exceptions", true)