Learn

What is a proof-of-work CAPTCHA?

A proof-of-work CAPTCHA asks the visitor's browser, not the visitor, to do a small computation before a form is sent. Nobody reads a distorted word or picks out traffic lights. The device does some arithmetic, and the server checks it.

Last updated

The idea

A classic CAPTCHA tries to tell people from programs by giving them a task that people find easy and programs find hard. Proof of work gives up on telling them apart. It puts a price on every submission instead, paid in computing time, and makes that price small for one person sending one message and large for a program sending thousands.

The idea is older than the web forms it now protects. Hashcash, proposed in 1997, used the same trick against email spam: a sender had to spend a little CPU time on every message, which nobody notices for one email and which adds up fast for a million.

How it works

Every proof-of-work scheme for forms follows the same four steps.

  1. The server issues a task. It is signed, so the browser cannot invent an easier one, and it expires, so a solution cannot be saved up and reused next week.
  2. The browser solves it. This is ordinary JavaScript doing ordinary arithmetic, with nothing drawn on the screen.
  3. The form carries the solution. It rides along as a hidden field next to the visitor's own fields.
  4. Your server checks the solution before it accepts the form. Checking is cheap; finding the solution was not. That asymmetry is the whole point.

In Botpoison Challenge, nothing runs while the page loads. When the visitor presses Send, the browser library fetches a signed task, solves it and adds the solution as one hidden field, _botpoison. Your server passes that field to /verify with its secret key. A solution is good once: a second check of the same solution fails.

Two kinds of work

The most common kind is a hash search. The browser tries number after number until the hash of the task and the number starts with enough zeros. Each try is a lottery ticket, so the time it takes varies a lot from one visitor to the next: a lucky phone finishes at once, an unlucky one keeps going. Hashing is also exactly what specialised hardware is built to do fast, so a well-equipped sender has a large advantage over a phone.

The other kind is a time lock. The browser squares a large number over and over, a fixed number of times, and every step needs the result of the one before. There is no luck in it, so every visitor on the same device pays about the same, and the chain cannot be split across many cores to finish sooner. The server holds a secret that lets it work out the result in one step when it issues the task, so checking stays cheap.

Challenge uses a time lock: a chain of modular squarings on 2048-bit numbers. Arithmetic on large numbers is work where a fast server is far less ahead of a phone than it is at hashing, which keeps the price closer to fair for the visitor.

What it costs a visitor

Nothing they have to do. There is no widget, no checkbox and no image grid, so there is nothing to fail, and screen reader users and keyboard users send the form like everyone else.

The cost is a short wait after Send. The browser library loads async, so the page does not wait for it.

A visitor can still be stopped when their browser cannot run the check at all. That happens when:

  • JavaScript is off.
  • Something blocks the script or the API: a content blocker, a corporate filter, or a Content Security Policy that does not allow them.
  • The browser is too old to run the arithmetic.

The library fires botpoison-challenge-error in those cases, so the page can tell the visitor what happened and offer another way to reach you.

What it costs a bot

A script that posts straight to your form handler without running the check sends no solution, or a made-up one, and your server turns it away. That removes the cheapest kind of form spam outright.

A bot that does run the check pays for it on every single submission, because every solution is new and is good once. A short wait is nothing to a person writing to you. Multiplied by every form on a spam list, it is the difference between a campaign that pays and one that does not.

What it does not stop

Proof of work prices bots. It does not detect them, and so:

  • It does not stop headless browsers. A real browser driven by a script runs the library and passes the check like any visitor. It makes every one of those submissions cost CPU time, which is a different promise from stopping them.
  • It does not stop spam typed by people. Someone typing you an SEO pitch passes the check without noticing. See why spam gets past your CAPTCHA.
  • It does not stop a sender who is happy to pay. A slow, targeted campaign against one form costs little CPU time in total.

That is why a challenge works best as one layer among several. The guide to stopping contact form spam walks through the others.

Trade-offs against other CAPTCHAs

Against an image CAPTCHA, proof of work wins on friction and accessibility: nobody is asked to prove anything. It loses on one point. An image puzzle at least tries to keep out a program that looks like a browser, and proof of work does not try.

Against a risk score such as reCAPTCHA v3, proof of work needs no profile of the visitor. A risk score has to observe the browser and its behaviour to judge it, and in the EU that has drawn the attention of regulators; see reCAPTCHA and the GDPR. Challenge sets no cookies and stores nothing in the browser. The flip side is that a risk score can act on what it observes, and proof of work only charges a fee.

Pairing it with a classifier

The spam proof of work cannot see is the spam a person wrote. That needs something that reads the message. Classify does that from your server: it returns spam or clean with a score, and you choose what happens to each. Challenge turns away the bulk before it is sent, and Classify reads what got through. Both are on one plan, and you can start free.

Where Botpoison fits. Stop the bots, then read the rest

Challenge

An invisible check for bots, before the form is sent.

Classify

A verdict on every message: spam or clean, with a score.

Get started with Challenge

Protect a form in three steps: the public key on the form, the secret key on your server.

Free to start

One plan, an allowance for each product. No credit card needed.

Keep reading

How to stop contact form spam

Honeypots, rate limits, a challenge, a content classifier and a review queue: which spam each layer stops, and which it lets through.

Last updated

Why spam gets past your CAPTCHA

Much of the spam that still arrives was typed by a person. A test for humans cannot stop it, and reading the message can.

Last updated

What is an invisible CAPTCHA?

Risk scores, browser challenges and proof of work all call themselves invisible. What each one does, and what invisible means for accessibility.

Last updated

Honeypot fields: how they work and where they fail

A hidden field that only bots fill in. How to build one that people and password managers leave alone, and which bots walk past it.

Last updated

reCAPTCHA and the GDPR: what EU regulators decided

The French CNIL and an Austrian court both found that reCAPTCHA needed consent. What they decided, and the questions it leaves for a form.

Last updated

Botpoison stops spam, not leads

Stop spam now
No credit card required
Invisible
Accessible
Two products, one plan