Spamming and DDoS attacks have increased by a large margin in the past few years. While there are already a lot of rigid mitigation methods for guarding against lower-layer attacks(such as SYN or ICMP flooding, Smurf attack, DNS amplification, and more), implementation on application layer prove to be more troubling.
Application layer DDoS mitigation requires the service itself to differentiate between bot and human, in order to provide services only to legit human users and to curb mass spamming. Attempts at so-called Turing tests were implemented to do so, hence the original captchas. However, bot-makers rendered them useless with text recognition powered by machine learning.
Google then led the switch to image-based ReCaptcha, which is seriously very bad user experience, due to the fact that to make the test harder for bots, the images are barely categorizable in plenty cases. Personally, I really hate Recaptchas, especially when the topic is something like “Choose all the Bridges”. Therefore, I decided to provide an easy alternative with a much better UX: “simply wait for your browser does the rest for you”.
Project Link: PoW Shield.
We aim to provide the following services bundled in a single webapp / docker image:
- proof of work validation
- ratelimiting and ip blacklisting
- web application firewall
So basically, PoW Shield works as a proxy in front of the actual web app/service. It conducts verification via proof-of-work and only proxies authorized traffic through to the actual server. The proxy is easily installable, and is capable of protecting low security applications with a WAF.
Here’s what happens behind the scenes when a user browses a PoW Shield-protected webservice:
The server generates a random hex-encoded “prefix” and sends it along with the PoW Shield page to the client.
Browser JavaScript on the client side then attempts to brute-force a “nonce” that when appended with the prefix, can produce a SHA256 hash with the number of leading zero-bits more than the “difficulty” D specified by the server. i.e. SHA256(prefix + nonce)=0…0xxxx (binary, with more than D leading 0s)
Client-side JavaScript then sends the calculated nonce to the server for verification, if verification passes, the server generates a cookie for the client to pass authentication.
The server starts proxying the now authenticated client traffic to the server with WAF filtering enabled.
That's it. Please feel free to reach out to me if you got any suggestions, and/or you wanna give a hand in making it better!
Top comments (0)