1

When upgrading from rack-attack 6.3.1 to 6.5.0 request object is unable to fetch any custom methods

When I run request.comment it throws the below error

undefined method `comment' for #Hash:0x00007fd2b4f41530

As per the documentation, I updated the method from throttled_callback to throttled_response

Rack::Attack.throttled_response = lambda do |request|
  details = {restriction: {name: 'asdas', comment: request.comment}}

  
  if Feature.enabled?(:some_feature)
    restrict_user(request.token, details) if request.update_password?
  end
end


I have added a lot of method but now after upgradating unable to access any of the method inside the throttled_callback

class Rack::Attack
  class Request < ::Rack::Request
    ##
    ## Helper Functions
    ##
    # Get the real IP Address of the user/client
    attr_accessor :comment

    def remote_ip
      @remote_ip ||= get_header('HTTP_X_FORWARDED_FOR').try(:to_s)
    end

    def body_params
      unless @body_params 
        @body_params = JSON.parse(body.read)
        body.rewind
      end
      @body_params
    end

    def username
      (body_params["username"]).to_s.downcase
    end

    def login?
      self.path == '/user_sign_in'
    end
end

throttle("ip:user-key-min", limit: 10, period: 1.minute) do |req|
  if req.login?
    req.comment = "some comment"
    req.remote_ip
  end
end

When I am inside the throttled_response. So, the request object is not able to access the comment or any method inside the class Request < ::Rack::Request after upgrading to the latest version of rack-attack. In version 6.3.1 in the request object I was able to access the method from the class Request < ::Rack::Request inside the throttled_callback

request.methods
[ :comment, :username, , :comment=, :body_params, :remote_ip, :login?]
Aniket Tiwari
  • 3,561
  • 4
  • 21
  • 61

1 Answers1

-1

Implementation of throttled_response is not exactly same as that of throttled_callback. In throttled_callback request object is accessible hence you are able to access all the methods but in throttled_response env object is passed.

See throttled_response Implementation here

Rack::Attack.throttled_response = lambda do |env|
  # NB: you have access to the name and other data about the matched throttle
  #  env['rack.attack.matched'],
  #  env['rack.attack.match_type'],
  #  env['rack.attack.match_data'],
  #  env['rack.attack.match_discriminator']

  # Using 503 because it may make attacker think that they have successfully
  # DOSed the site. Rack::Attack returns 429 for throttling by default
  [ 503, {}, ["Server Error\n"]]
end
  • I understand the method definition is different. My Quesiton is if i have to use custom method then how can I use it with throttled_response. Also, the link which you have given is wrong. – Aniket Tiwari Sep 27 '21 at 10:26
  • Hey, I have updated the link in the comment above. And to call a custom method you need to have some object in `throttled_response` method. As per the implementation only ENV is passed to it. – Ayush Billore Sep 27 '21 at 13:37
  • What do you mean by some object? Can you give an example by showing a request.comment or object.comment is accessible – Aniket Tiwari Sep 30 '21 at 05:38