PoW Shield: An Application Layer Proof of Work DDoS Filter

Written by ruisiang | Published 2021/03/16
Tech Story Tags: ddos-mitigation | how-to-prevent-ddos-attacks | network-security | cybersecurity | computer-security | dos-attacks | verification | identity-verification

TLDRvia the TL;DR App

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 an application layer can prove to be more troubling.
Application layer DDoS mitigation requires the service itself to differentiate between a bot and a 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 a very bad user experience. Because it makes the test harder for bots, the images are barely categorizable in plenty of 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 to do the rest for you”.

How it Works

PoW Shield provides DDoS protection on the OSI application layer by authenticating traffic using a simple proof-of-work validation process.
So basically, the PoW Shield works as a proxy in front of the actual web app/service. It conducts verification and only proxies authorized traffic through to the actual server. The proxy is easily installable and is capable of protecting low-security applications.
Here’s what happens behind the scenes when a user browses a PoW Shield-protected web service:
  1. The server generates a random hex-encoded “prefix” and sends it along with the PoW Shield page to the client.
  2. The 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)
  3. The 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.
  4. The server starts proxying the now authenticated client traffic to the server.

Installation and Configuration

Simply clone the repository to the server you want PoW to run on, install dependencies, edit configurations, and you’re all set.
Here’s a detailed walkthrough:
# 1.clone repo
# 2.install dependencies
npm install
# 3.copy sample configuration
cp -n .env.example .env
# 4.edit .env(we'll cover this later)
# 5.build JavaScript files(project is in TypeScript)
npm run build
# 6.start PoW Shield
npm start
Configuration explanation:
  • SESSION_KEY: secret key for cookie signatures, use a unique one for security reasons, or anyone can forge your signed cookies
  • WAF: toggles WAF functionality on/off (WAF is a work in progress)
  • POW: toggles PoW functionality on/off (if not temporarily switched off, why use this project at all?)
  • NONCE_VALIDITY: specifies the maximum time a nonce has to be submitted to the server after generation (used to enforce difficulty change and filter out stale nonces)
  • INITIAL_DIFFICULTY: initial difficulty, number of leading 0-bits in a produced hash (0:extremely easy ~ 256:impossible, 13(default): takes about 5 seconds for the browser to calculate)
  • BACKEND_URL: location to proxy authenticated traffic to, IP and URLs are both accepted

Future Work

  • WAF: additional web application firewall to provide an extra layer of protection
  • IP Blacklisting: block IPs spamming nonce calculation results automatically
  • Dynamic Difficulty: alter difficulty base on bandwidth and number of requests
  • Unit Testing: unit testing for services and library
  • Dockerization: make it even easier to use
  • Multi-Instance Syncing: sync blacklist and authentication information between multiple instances for deployment on multiple instances behind a load-balancer

Final Words

PoW Shield is currently still a work in progress, feel free to lend me a hand on implementing these features or providing suggestions (features or optimization).

Written by ruisiang | Blockchain and Backend Developer Privacy Advocate Crypto Enthusiast
Published by HackerNoon on 2021/03/16