The Case of reCAPTCHA Session Validation Errors
Happy holidays everyone. We’ve had three sites in the last two weeks that have reported reCAPTCHA problems. A captcha is the funny little thing at the end of forms that tries to prove you’re not a robot by having you spell out letters, or pick pictures with traffic lights. They’re annoying, but without them, many “contact us” forms and user registration forms can be hit with a crippling amount of spam submissions.
Newly discovered reCAPTCHA session validation errors (TL;DR)
One of our clients even recently called in for holiday support on this bug, so we’re pretty sure there are others dealing with this situation as well. They all have the same JS error and/or symptom:
CAPTCHA validation error: unknown CAPTCHA session ID. Contact the site administrator if the problem persists.
Diagnosing the session validation error
The root of this error, at least for one of our sites using simple_reCAPTCHA, is pretty straightforward (but took us days to diagnose initially). There are two parts to the issue. A typical contact us page has 2-3 forms on the page: Search, Email Sign Up, and the contact form. The submit button for each one has the same HTML ID. That's not valid HTML; IDs have to be unique. There's code in the reCAPTCHA, captcha, and simple_reCAPTCHA modules that get tripped up because of caching.
Each part (block) on the page is cached separately, so when someone visits the homepage and that gets cached, Drupal also just pulls the search form from its cache for other pages instead of rendering it from scratch.
If rendering the whole page from scratch, Drupal uses unique IDs in every form. One's submit button has the id #edit-submit, another gets #edit-submit--2, the other #edit-submit--3. But due to the caching behaviour with reusing existing blocks, we end up with:
- If you visit the homepage, which just has the search form, its button gets #edit-submit.
- When you visit the contact page, which has 2 forms that need to be rendered, the Sign-Up and contact form, Drupal uses ids #edit-submit and #edit-submit--2. But the cached search form also ends up in the header with an id of #edit-submit too.
Similarly, the captcha and reCAPTCHA module loads the token, but it gets stored in the cache and it causes the same or similar error that simple_recaptcha does.
Helping reCAPTCHA modules deal with Drupal caching
The real bug is challenging and not fixable within our support scope of practice. More on the accessibility concerns and other issues below.
- If you’re using the captcha module, we recommend reviewing the discussion and various patches in #3089263.
- For the reCAPTCHA module, perhaps consider using one of the other two modules instead.
“It may sound minor, but it's a major issue, as it is associating the search autocomplete functionality in the header with the views filters elements in the content. The end result is that JAWS thinks a regular select element in the views filters, is a combobox, which it is not, so it's pretty confusing to users.”
So it’s not just captcha related and is definitely going to need some real consideration from the caching experts that work on that piece of Drupal. Let us know on Twitter if you’re having the same issues and how you fixed them.