This content originally appeared on dbushell.com (blog) and was authored by dbushell.com (blog)
Look what I made! I’ve been
My new project Anoobis is an experimental implementation of Anubis I made with JavaScript, Zig, and Wasm. But what is Anubis?
Weigh the soul of incoming HTTP requests using proof-of-work to stop AI crawlers
Anubis is a PoW (proof of work) CAPTCHA designed to block weaponised “AI” from DDoS-ing web servers. Unlike traditional CAPTCHAs, Anubis actually works.
Are those pixels part of a traffic light? Who knows! Well bots do, reCAPTCHA v2 is bust yet continues to plague the web. hCaptcha is “Accessibility Theater” and thus not fit for purpose either. Tarpits and poisoning wells are one way to fight back if you can afford the bandwidth. Otherwise, Anubis might be your answer.
Proof of Work
PoW CAPTCHAs force a web browser to calculate SHA-256 hashes until it generates one that matches a given criteria. This is usually a specific number of leading zeros (the difficulty). Due to the nature of cryptography there are no shortcuts. Once the answer is known it can be verified instantly; the proof-of-work. Other PoW exists but hashing is most common.
Anubis acts as a reverse proxy web server. HTTP requests are checked for a PoW cookie. Without a valid cookie the request is not forwarded and a challenge page is served instead. Successfully completing the PoW rewards a valid cookie that permits access through the reverse proxy for limited time.

Challenges are unique to each visitor based on data like IP address and user-agent header. A rotating date, such as midnight last Monday, is added to the challenge data to automatically renew it and invalidate cookies after a specific time period.
Browsers calculate the PoW within a few hundred milliseconds. This is nothing for a single human visitor. For botnets the cumulative PoW is significant and costly. At least that’s the idea. I suspect most bots simply cannot execute the challenge.
My Anoobis
As an educational exercise† I implemented my own version of Anubis called Anoobis. I love a bit of Zig and Wasm so I used that for the PoW.
† I’m totally deploying this to prod! More on that later…
I coded a proof-of-concept reverse proxy in Deno flavoured TypeScript. This is not suitable for production. Anubis proper uses Go for that purpose. Although I built Anoobis as a reverse proxy it’d be better suited as entry middleware gate-keeping a single JavaScript web server. I plan to build Hono middleware soon (update: done it.)
Learning Stuff
My Anoobis bundles the challenge page into a single HTML response including inline CSS, JavaScript, and Base64 embedded Wasm. At one request just over 5 KB (compressed) this is way lighter than the six requests and 380 KB of the real Anubis. Most of that weight comes from web fonts and an anime girl.

I’m sure we can all agree that web fonts are pure overhead but the necessity of an anime girl is up for debate. All I’ll criticise is the lack of consistant branding. May I suggest, anime Cleopatra?
I thought
Theoretically you need the fastest possible PoW algorithm in browsers. The difficulty has to be adjusted for web browsers ensuring it takes long enough, but not too long. If a bad actor can solve the PoW faster without a browser it makes the entire game pointless.
PoW CAPTCHAs require JavaScript. The challenge is only sent for text/html
requests. Other requests return 404 until the cookie is set. This could cause issue with front-end caching strategies if not done carefully.
“Good bots” need to be considered too. Especially if you care about search engines. My version does nothing to separate good from bad.
You can find my Anoobis on GitHub. Don’t use it. Use Anubis!
This content originally appeared on dbushell.com (blog) and was authored by dbushell.com (blog)

dbushell.com (blog) | Sciencx (2025-06-07T10:00:00+00:00) Weighing Souls with Anubis at Home. Retrieved from https://www.scien.cx/2025/06/07/weighing-souls-with-anubis-at-home/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.