5 ms·
Two weeks ago my website [0] got hit by a botnet attack. These bots were submitting 2 POST requests to /login, followed by 2 POST requests to /signup, and since
by jmstfv 7y ago
Two weeks ago my website [0] got hit by a botnet attack. These bots were submitting 2 POST requests to /login, followed by 2 POST requests to /signup, and since there were no checks in place, they were getting in quite easily. All their requests originated from residential IP addresses (probably hacked IoT devices) so IP blocking seemed impossible. I knew I needed to do something, but didn't want to send my users' data to Google.
I settled on implementing a honeypot technique using invisible_captcha gem [1]. It uses multiple techniques to detect bot activity, such as checking if the form was submitted too fast, hidden form attribute only visible by bots but not humans, etc...
Luckily for me, these bots weren't quite sophisticated so I managed to clamp down on their activity. I still get a couple of bogus signup attempts every day.
Disclosure: I am a contributor to the invisible_captcha gem
[0] https://tryhexadecimal.com https://tryhexadecimal.com
[1] https://github.com/markets/invisible_captcha https://github.com/markets/invisible_captcha
EDIT: grammar and wording
- fractalf 7y agoVery interesting idea (the invisible captcha approach)! Since you are a contributer, can you tell us how efficient this strategy is? I mean, do you still experience advanced bots being able to still act as humans?
- jmstfv 7y agoThey still try to sign up, but none of them can actually bypass the captcha. I implemented a custom callback that returns a HEAD response with 404 to fool them (because I noticed that attacks intensified when I returned 2xx or 3xx responses).
- fractalf 7y agoTHIS is what I'm talking about :) Great work! Seems to me this is very centered on Rails apps. Would it be possible to do somethink like this for "everyone"? I have nothing agains Rails, but as a js/php/python develper myself, I wouldn't know where to begin with this..
- jmstfv 7y agoThe easiest way to start would be introducing an invisible form field [0] and on submission, checking if it is not empty. Give this form field a random name so that it wouldn't be populated by password managers. You can take it one step further and check how fast the form was submitted. If it is below the predefined threshold, it is probably a bot. [0] To hide the form field, you can use one of these snippets, interchangeably: "display:none;" "position:absolute!important;top:-9999px;left:-9999px;" "position:absolute!important;height:1px;width:1px;overflow:hidden;"
- Master_Odin 7y agoIt should be stated that you should either use the first approach (display none) or give a 0 height/width, so that screen readers don't pick up these fake fields and ruin accessibility on your form.
- throwaway_bad 7y agoUnfortunately anything screen readers can recognize as invisible, a more sophisticated bot can too.
- shakna 7y agoThere's also aria-hidden to prevent screen readers from touching the honeypot field.