Improperly Configured rack_attack.rb does not prevent rate limit attacks in lobsters/lobsters
Reported on
Jul 6th 2022
Description
The lobsters repository depends upon rack_attack.rb to prevent rate limit attacks against the /login
or the /login/set_new_password
endpoint, allowing for only 4
requests in a minute. However, this can be bypassed by simply appending some strings like /login.turtles
to the endpoint.
Proof of Concept
$ while true; do curl -ikIL "https://mysite.com/login.turtles" -X POST -d "{'username': 'itsmemario'}"; done
Impact
This can allow an attacker to bypass rate-limit checks and brute-force login attempts. (See References for further readings)
Occurrences
rack_attack.rb L22
The vulnerability arises due to the following lines of code:
Rack::Attack.throttle("login", limit: 4, period: 60) do |request|
request.ip if request.post? &&
(request.path == '/login' || request.path == '/login/set_new_password')
end
The main vulnerability arises due to the fact that request.path
is an absolute. With a bit of junk injection, we can append random strings of characters to the protected directory.
SECURITY.md
a year ago
Thanks for reporting this. I've updated it:
diff --git config/initializers/rack_attack.rb config/initializers/rack_attack.rb
index e9557830..5a8e54bd 100644
--- config/initializers/rack_attack.rb
+++ config/initializers/rack_attack.rb
@@ -18,8 +18,10 @@
end
# at some point they'll proceed to testing credentials
Rack::Attack.throttle("login", limit: 4, period: 60) do |request|
- request.ip if request.post? &&
- (request.path == '/login' || request.path == '/login/set_new_password')
+ request.ip if request.post? && (
+ request.path.starts_with?('/login') ||
+ request.path.starts_with?('/login/set_new_password')
+ )
end
Rack::Attack.throttle("log4j probe", limit: 1, period: 1.week.to_i) do |request|
Committing and deploying this fix is backed up behind an unrelated security fix, which unfortunately broke the prod site yesterday when I deployed it: https://github.com/lobsters/lobsters/commit/cf9bb59333b4ea8344918e05a6e2dcb6c7d0e46c
I hope to sort that out and land this fix tonight after work.
Thanks. Can you please mark the report as verfied? That would really be helpful. Also, if you want to have a more comprehensive report about the vulnerability and let users know about it do that they can fix it ASAP, I guess @admin can also arrange for a CVE for you guys once it has been patched. That way, it'll be easier to document, detect and remediate 😃
Across different systems, CVE IDs give users a reliable way to recognize unique vulnerabilities and coordinate the development of security tools and solutions. Read more about it here.
Sorry, I don't see any UI for doing that?
I don't know why we'd need a CVE, we're one website with a one-line bug that's not seeing abuse. Can't say I know much about the CVE process though. I've already written the patch, the only reason it's not deployed is the unrelated breaking change in Rails 7.0.3.1.
I've deployed this fix: https://github.com/lobsters/lobsters/commit/190ce7cba563ac9df5492af388e889a574d28e84
Thanks for validating the report. Also, I see that you marked the report as a low-severity. However, another very well know project had the same exact vulnerability and was reported as High because this misconfiguration can also lead to DoS attacks. Just putting it out there for future references.
This site doesn't really do a great job of explaining itself, it has zero explanation what the consequences of any of these actions will be or what their definitions are. I don't see that I can do anything about it now, sorry.