-
Notifications
You must be signed in to change notification settings - Fork 337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make it possible to block requests based on response. #646
base: main
Are you sure you want to change the base?
Conversation
➕ |
1 similar comment
➕ |
assert_equal 200, last_response.status | ||
end | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spec/acceptance/postrequest_spec.rb:29:1: C: [Correctable] Layout/EmptyLines: Extra blank line detected.
spec/acceptance/postrequest_spec.rb:51:1: C: [Correctable] Layout/EmptyLinesAroundBlockBody: Extra empty line detected at block body end.
68 files inspected, 2 offenses detected, 2 offenses auto-correctable
RuboCop failed!
@type = :postrequest | ||
end | ||
|
||
def matched_by?(request, response) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that this method calling twice:
- the first time before
app.call
- the second time after
app.call
I guess that we can accidentally mark a request as matched even when it doesn't blocked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mb change postrequest.matched_by?
to postrequest.block.call
?
#lib/rack/attack/configuration.rb
def process_postrequests(request, response)
@postrequests.each { |_name, postrequest| postrequest.matched_by?(request, response) }
end
@santib The solution is feet to the gem philosophy? Is there any chance the PR to be accepted? I would like to have the opportunity to use this feature in my projects. |
Hi @NOX73 and @seliverstov-maxim 👋 First of all, thanks for your contribution. I've been thinking about this PR for some days already, but didn't comment because I haven't formed an opinion just yet. You said that the reason to add this feature is because
Would you be able to expand it a bit more? Like why do you want to do it only based on 4xx? Why wouldn't throttling or blocklist+fail2ban be enough for your use case? |
Sure, no problem. Some scanning programs scan some URLs, but there are some clients who might put same load, like the same requests per time. The only different we see - it's the response. In the scanning case it a lot of 404 errors. So would be very helpful to ban them based on what status code the request ended with. |
@NOX73 Honestly, I'm not sold on adding this feature to |
@santib Do you think it does not fit the gem idea, or is it our corner case? Sure I think it might be a separate gem, why not. I just was surprised there is no way to implement such common (in my opinion) functionality. |
Sounds good to me |
This seems totally reasonable to include in the RackAttack gem itself. I don't like the idea of having to make this a separate gem. |
@seliverstov-maxim @NOX73 Hello, i have more or less same use case. We have a public API and some of our customers use our API in wrong way, so we returns errors. I would like to add throlling when there is too many errors in a period. Like "error limits exceeded". |
I investigated the point "I mean something like a rack-attack extension (e.g. rack-attack-postrequest)" |
➕ Any suggestions for a temporary workaround? I was thinking about caching response codes and basing the throttle/blocking logic based on those cached response codes |
I think this fits with the overall goal of Additionally, if we're talking about supporting extensions then some of I have a use case for this. A side project of mine has been subjected to some account spam. Bots used by spammer send requests that cause Currently, in order to handle that case, I'd need to replicate a lot of controller logic in my |
My use case is to prevent brute forcing things like login. If there are N failures I want to block anyone from logging in to this account for some time, say a day. Because this logic is based on the response code there is no good way to make it work with |
I want to use rack-attack to block pentesters based on 4xx requests. It's not possible with the current gem API.
So here is a POC how it might look like:
It might look clumsy, but you have to check if a response exists with such API.
So, I'm ready to add more specs and finish this to get it ready to merge if you think this is a good idea.
Naming is also debatable.