# CAPTCHAs with no way past them except solving the puzzle

Source: https://easeweb.dev/learn/captcha
Topics: Page structure > CAPTCHAs have an alternative that needs neither sight nor a puzzle (WCAG 1.1.1, 3.3.8)
The fix: Take the CAPTCHA off the sign-in and stop repeated attempts on the server instead. Where it has to stay, describe its purpose in its text alternative, offer the characters as audio too, and put a way in that needs no test, such as an emailed sign-in link, beside it.
Test with: screen reader, keyboard, sound off, screen off
References: https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-minimum.html https://www.w3.org/WAI/WCAG22/Techniques/general/G143 https://www.w3.org/WAI/WCAG22/Techniques/general/G144 https://www.w3.org/WAI/WCAG22/Techniques/general/G218 https://www.w3.org/TR/turingtest/

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

## What happens

A concert ticket site asks for an email address and a password. After two wrong passwords, the sign-in page adds a box under them: an image of six distorted letters and numbers, a field labelled "Type the characters you see", and the Sign in button. The site added it to slow down programs that try password after password. A screen reader user who mistyped their password twice hears "CAPTCHA, image", then "Type the characters you see, edit text". The alt text says what the picture is, but not what it shows, which is the point of a CAPTCHA, and there is no audio version and no other way in. They can't buy the tickets. A sighted visitor with dyslexia can't tell whether it says "7KX4P2" or "7KX4PZ", and gets a new image for each wrong guess.

The same step fails in other ways:

- The image has no alt text at all, so a screen reader reads its file name, or nothing.
- A puzzle asks people to drag a piece into a gap, or to solve a sum, with no other way in.
- A grid of photos asks people to pick every picture with a bus, with no audio version and no way to skip it.

## Why it fails

Success criterion 1.1.1, Non-text Content, is level A. A CAPTCHA is one of the few images whose text alternative doesn't have to say what it shows, since saying it would give the answer to every program. In its place, the criterion asks for two things: a text alternative that identifies and describes the CAPTCHA's purpose (technique G143), and another form of CAPTCHA that uses a different sense, such as audio beside an image (G144). This one has neither: "CAPTCHA" names the picture without saying what to do with it, and nothing but sight can get past it.

Success criterion 3.3.8, Accessible Authentication (Minimum), is level AA and new in WCAG 2.2. On a sign-in, reading characters from an image and typing them back is transcription, a cognitive function test, and no step of signing in may rely on one unless the step also offers a way in that needs none, or something that helps. The Understanding document says an audio CAPTCHA doesn't count as that alternative, because typing what you hear is transcription too. Recognising objects, such as picking out the buses, is an exception at this level; reading characters, sums and puzzles are not.

## Who is affected

The CAPTCHA appears after a mistake, so it falls hardest on the people most likely to have just made one: those typing a password from memory, with a screen reader, a switch or an on-screen keyboard.

## What automation and AI miss

The image has alt text, so axe and other scanners pass it; none of their rules can tell that the alt text names a CAPTCHA rather than describing its purpose, or that nothing else on the page offers another way. The CAPTCHA here appears only after two failed sign-ins, so a scan of the page as it loads never sees it, and neither does EaseWeb's audit, which never mistypes a password on purpose. Where a CAPTCHA is on the page from the start, the audit lists up to five CAPTCHAs it recognises on each page it reaches, the common services' widgets and images whose address or alt text says CAPTCHA, as a lead: a person has to check whether a second sense is offered, and on a sign-in, a way in that needs no test. A code assistant asked to protect a form from bots may reach for a CAPTCHA widget first, and asked to make one accessible, can write alt text that spells out the characters, which hands the answer to every bot.

## Before: an image CAPTCHA with nothing else

```html
<form action="/sign-in" method="post">
  …
  <img src="/captcha" alt="CAPTCHA">
  <label for="captcha">Type the characters you see</label>
  <input id="captcha" name="captcha">
  <button type="submit">Sign in</button>
</form>
```

The `…` stands for the email and password fields, which stay as they are. The only way past is to see the image and read its characters: the alt text names it without saying what it is for, nothing offers the characters to another sense, and nothing lets people sign in without solving it.

## After: no CAPTCHA, with attempts limited on the server

```html
<form action="/sign-in" method="post">
  …
  <!-- No CAPTCHA: the server limits attempts per account and per address. -->
  <button type="submit">Sign in</button>
</form>
```

The sign-in asks nothing more of anyone, so there is nothing to pass and nothing to fail. The CAPTCHA's job moves to the server: it allows a few wrong passwords for an account, then slows further attempts or locks the account until the person follows a link sent by email, and it limits how many attempts one address can make across all accounts. Those limits stop the programs that try password after password, without a test for the person at the keyboard.

## After: a purpose, a second sense and a way in with no test

```html
<form action="/sign-in" method="post">
  …
  <img src="/captcha" alt="Characters to type, to check you're a person. You can also listen to them below.">
  <p id="captcha-listen">Or listen to the characters:</p>
  <audio controls src="/captcha/audio" aria-labelledby="captcha-listen"></audio>
  <label for="captcha">Type the characters you see or hear</label>
  <input id="captcha" name="captcha">
  <button type="submit">Sign in</button>
  <button type="submit" formaction="/sign-in/email-link">Email me a sign-in link instead</button>
</form>
```

The alt text now says what the image is for and where the alternative is, without giving its characters away (G143), and the same characters can be heard from an audio player, a second sense (G144): that passes 1.1.1. The second button sends the form to an address where the server emails a link that signs the person in, with nothing to solve or type but the email address (G218): that is the way in with no test that 3.3.8 asks for. It is for a site that has to keep the CAPTCHA, such as one whose CAPTCHA comes from a security vendor's settings.

## After: an audio version only

```html
<form action="/sign-in" method="post">
  …
  <img src="/captcha" alt="Characters to type, to check you're a person. You can also listen to them below.">
  <p id="captcha-listen">Or listen to the characters:</p>
  <audio controls src="/captcha/audio" aria-labelledby="captcha-listen"></audio>
  <label for="captcha">Type the characters you see or hear</label>
  <input id="captcha" name="captcha">
  <button type="submit">Sign in</button>
</form>
```

The purpose and the second sense pass 1.1.1, so a blind visitor can listen to the characters and type them in. It isn't enough on a sign-in. Typing what you hear is still transcription, so 3.3.8 still fails: people who can't hold six characters in mind still have to, and type them back in order, and people who can neither see nor hear have no way past at all.

## Which option to use

The first two pass both criteria; the audio version alone passes 1.1.1 only. Take the CAPTCHA off: limits on the server stop the same programs, and the sign-in then has nothing to solve, where the second option still puts a test in front of everyone who doesn't notice the link. Keep a CAPTCHA only when a vendor or a policy you can't change requires it, and then give it all three parts. Use the audio version alone on a form that isn't a sign-in, such as a contact form, where 3.3.8 doesn't apply, and even there prefer checks that ask nothing of people.

## Implementation decisions

Never put a CAPTCHA's answer in its alt text, its file name or the page: it gives the answer to the programs it is meant to stop. Describe what it is for, and let the audio carry the characters.

Make the audio controls a native `audio` element or a real button, reachable with the keyboard, and let the audio be played again: many people need to hear the characters more than once. Don't make the challenge expire while someone is listening.

CAPTCHA services that score each visit in the background ask nothing of most people, which helps; but check what they show the visitors they doubt, because that can be a picture puzzle like the ones above, and then it needs the same alternatives. A hidden field that only programs fill in, and limits on how often one address can send a form, do the same job on other forms.

Picking pictures of objects, such as buses or traffic lights, is excepted from 3.3.8 at AA, but it still needs a second sense under 1.1.1, and it fails 3.3.9, the AAA version, which has no such exception.

The rest of signing in needs the same care: a password field that refuses paste is the same failure of 3.3.8; see [password fields that won't take a pasted password](/learn/password-paste).

## Verify the fix

1. With a screen reader, and with the screen off, go through the sign-in to the point where the CAPTCHA appears, and confirm you can get past it without sight: by the audio, or by a way in that needs no test.
2. With the sound off and the image hidden, check what is left: on a sign-in, there must be a way in that needs neither, such as an emailed link.
3. Use the way in that needs no test from start to finish, and confirm it signs you in without solving anything.
4. With only a keyboard, reach and use every part of the step: the audio controls, the answer field and each button.

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the CAPTCHA service, its settings or the sign-in form change.

## Limits

This is a starting pattern, not a guarantee for every form. Every CAPTCHA shuts out someone: an audio version doesn't help people who are deaf-blind, and an emailed link doesn't help someone who can't reach their email, so the surest fix is not to ask people to prove they are people. 3.3.8 covers signing in; a CAPTCHA on a contact form or a checkout falls under 1.1.1, not 3.3.8, but it shuts out the same people. Test the whole flow, including what appears only after a mistake, with the tools your users rely on.

---

Get this guide in your coding agent: MCP https://easeweb.dev/mcp (setup at https://easeweb.dev/services/developers)
