This is also reported in reCAPTCHA module: #2219993: Enable cacheable captcha support (once 2449209 is committed)

Summary:
reCAPTCHA has "ajax API", which can be used to re-enable caching on Form pages with reCAPTCHA. The problem is that it is currently incompatible with the current captcha API and the "captcha session".

How Captcha works:
- With rendering of the form "captcha session" is initialized, the captcha is generated and the correct "solution" is inserted in the record for "captcha session".
- When submitting the form user provides "captcha response", and it is being checked if it is identical with the "solution". If it is, then captcha validation is successful, and the user is not a bot.

How reCAPTCHA ajax API works.
- With javascript the reCAPTCHA is generated on a cached page.
- The reCAPTCHA is different despite the page being cached.
- When user submits the reCAPTCHA the "recaptcha response", along with information that identifies the "recaptcha challenge" is posted to Drupal.
- Drupal will call the recaptcha service with that information and service will respond with success or failure, and the service will make sure that it will only succeed once for the same challenge.

There is a POC for this in comment #4. What is left is to create a patch that will allow existing CAPTCHA functionality to work, and to still have the option for working cacheable and secure reCAPTCHA challenges.

Comments

miroslavbanov’s picture

Here is a first draft of the patch. It will allow for reCAPTCHA with Ajax API to be used with caching enabled. So we can have caching of forms with captcha. And don't forget that reCAPTCHA is accessible. Unfortunately with this patch only reCAPTCHA will work. Captcha modules that use the normal captcha session handling will not work (captcha validation will fail), because the session handling is completely gutted.

I am thinking that there should the option to have custom session handling built into the captcha module, with the option to manage it externally - in a lightweight PHP script, or maybe a nodejs. But I am not yet sure how to implement it in a very elegant way, while keeping compatibility.

nicrodgers’s picture

Perhaps this is a good case for using the Session API module?

miroslavbanov’s picture

I seem to have broken the patch with a last-minute change. I will add a working patch soon.

@nicrodgers
My goal is to keep the so-called "Captcha session" managed separately from Drupal, so it wouldn't need a Drupal bootstrap in order to generate or use it, and Session API module doesn't look like it will help in this scenario.

miroslavbanov’s picture

Category: Support request » Task
StatusFileSize
new9.04 KB
new1.34 KB

Here is a fixed patch. I have removed the disabling of cache under all conditions, and have made changes so only reCAPTCHA will validate correctly, and other CAPTCHAs currently will just be always correct. This is how I will be using it for a project in which performance is a high concern.

Here is the CAPTCHA part of my build:

projects[captcha][type] = "module"
projects[captcha][subdir] = "contrib"
projects[captcha][download][type] = "git"
projects[captcha][download][url] = "http://git.drupal.org/project/captcha.git"
projects[captcha][download][branch] = "7.x-1.x"
projects[captcha][download][revision] = "d873056becb1a85905ab512f1fce18397ecb16e1"
projects[captcha][patch][] = "http://www.drupal.org/files/issues/reCAPTCHA_ajax_API_compatibility-captcha-2449209-4.patch"

projects[recaptcha][subdir] = "contrib"
projects[recaptcha][version] = "1.12-rc1"
wundo’s picture

Project: CAPTCHA » reCAPTCHA
Component: Captcha API (captcha) » General

Wrong project, moving to ReCAPTCHA

miroslavbanov’s picture

Project: reCAPTCHA » CAPTCHA
Component: General » Captcha API (captcha)

@wundo

I intentionally created this issue in CAPTCHA module. It's not a mistake. Some adjustments to the CAPTCHA API are needed to support reCAPTCHA+caching. There already is an issue in reCAPTCHA about this.

miroslavbanov’s picture

Title: CAPTCHA session reuse attack detected, when using reCAPTCHA ajax API » CAPTCHA API to support (cacheble) reCAPTCHA with ajax API
Issue summary: View changes
nwom’s picture

Has anyone had any success with #4? Would love to use it, since we occasionally have the "CAPTCHA session reuse attack detected" error message. Thanks in advanced.

s_leu’s picture

#4 is workig for me

koppie’s picture

Status: Active » Fixed

I can confirm that upgrading to the latest dev version solves the problem.

We haven't had a stable release of this module since 2015, so hopefully we'll get one soon. In the mean time, I'm marking this issue as fixed.

miroslavbanov’s picture

@koppie
I guess you are not getting the annoying 'CAPTCHA session reuse attack detected' error. That's good.

The problem is that the pages with captcha are still not cacheable. It doesn't matter if you use recaptcha ajax API, and if you use latest dev version of captcha. If you think otherwise, can you direct me to a web page which is cached and uses recaptcha? It is easy to determine if it is cached by looking at the response headers.

miroslavbanov’s picture

Title: CAPTCHA API to support (cacheble) reCAPTCHA with ajax API » CAPTCHA API to support (cacheable) reCAPTCHA with ajax API
miroslavbanov’s picture

Status: Fixed » Closed (won't fix)

Let's have correct status. Issue is not fixed because pages are not cacheable.

koppie’s picture

@MiroslavBanov actually I did get it working with a cached page, with the new Google recaptcha checkbox functionality - see https://www.google.com/recaptcha/intro/index.html. Maybe that's the difference - I don't know if it works with the older "type in the word" recaptcha. Anyway you can see it in action here: http://www.starthub.org/eform/submit/submit-event

I hope that helps.

miroslavbanov’s picture

StatusFileSize
new22.64 KB

@koppie
I'm referring to full page cache, which you can cache in Varnish, and directly serve for different HTTP requests. Looking at the headers, I am think you always hit the backend. I've attached a screenshot to show.

koppie’s picture

@MiroslavBanov funny - it was caching yesterday. I swear! But of course I didn't take a screenshot.

FWIW, do you really need to cache the submission page? If you cache the other 99% of your site, and move forms to separate pages (no embedded/modal), you'll still see huge performance gains from caching, even on a heavily trafficked site. I know this is all moot since you've already closed the ticket - just trying to help.

miroslavbanov’s picture

I was just wondering (doubting) if it really is solved.

I created the patch in the past because of reasons that are now irrelevant. But I am still interested in the topic, and how far the modules have progressed, what has changed.

Probably with Drupal 8 the whole problem should be approached from different angle.

fabianx’s picture

Title: CAPTCHA API to support (cacheable) reCAPTCHA with ajax API » Add support for cacheable captcha's (recaptcha)
Status: Closed (won't fix) » Needs review

Re-opening as I got this to work for a client.

fabianx’s picture

This includes the fix for https://www.drupal.org/project/captcha/issues/2465113#comment-12370804, but an interdiff.txt is provided for easier review.

To explain a little bit:

recaptcha can just set:

$captcha['cacheable'] = TRUE;

in the 'generate' callback.

As recaptcha does not depend on any sid or solution it can be displayed on cached pages and therefore the page cache does not need to be disabled.

The only thing happening then is:

- A session re-use error is generated on the second usage of the cached form (for obvious reasons).

However this session re-use error is not a problem as the form still will validate correctly (as recaptcha uses its own $_POST values to check), therefore the error message can be just skipped.

A new sid and token are generated and the sid is (if the captcha passes validation) immediately set to solved. If the captcha does not pass validation, the captcha is displayed as normal.

To ensure that the message can be skipped, a new hidden element called 'captcha_cacheable' is introduced. As this only affects display logic (drupal_set_message()), there is no security problem.

Side effects

In case that someone would set a captcha to cacheable, which is not cacheable the only thing happening would be that the challenge would be deemed wrong and the user would need to enter it again.

However custom logic could be applied to hide the captcha until the form is actually submitted (e.g. display the captcha only on POST). This leads to a validation error, but for some sites that might be acceptable.

Therefore while this improves recaptcha in general, this would also allow more complex workflows (e.g. ajax based, 2nd page captcha) for all types of captcha's, so is also generally useful.

plach’s picture

Looks good and works well in combination with #2465113-2: Improve cache handling for non-displayed captcha's.

plach’s picture

Status: Needs review » Reviewed & tested by the community

.

miroslavbanov’s picture

#19

+1

Doing a basic test, this appears to work well with recaptcha 7.x-2.2 + the recaptcha patch. Tested with Contact module.

vijaycs85’s picture

+1 to RTBC. We'd need it to commit #2130615: Enable page caching

gomez_in_the_south’s picture

+1 to get this committed.
We're using the patch from this issue alongside that of #2130615 to allow our pages using Recaptcha to be cacheable.

wundo’s picture

wundo’s picture

Status: Reviewed & tested by the community » Needs work

Could you please re-roll?

vijaycs85’s picture

Status: Needs work » Needs review
StatusFileSize
new2.12 KB

Here is a re-roll.

vijaycs85’s picture

Looks like some environment issue with branch test @wundo, could you re-test it please?

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

Re-roll looks great to me!

Back to RTBC

  • wundo committed dee42a7 on 7.x-1.x authored by Fabianx
    Issue #2449209 by MiroslavBanov, Fabianx, vijaycs85, koppie, wundo,...
wundo’s picture

Status: Reviewed & tested by the community » Fixed
miroslavbanov’s picture

Status: Fixed » Needs work
StatusFileSize
new9.54 KB

I think the reroll overlooked something and a message is shown in cases where it shouldn't be shown, and it is shown twice in cases where it should be shown once.

miroslavbanov’s picture

Status: Needs work » Needs review
StatusFileSize
new563 bytes

Fixes issue from my previous comment.

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

Ugh, yes.

Good catch.

Back to RTBC for follow-up

vijaycs85’s picture

Sorry about that. I can see the bug on rerolled patch. +1 to RTBC

reinvented’s picture

With the end-of-life for Mollom coming in just three weeks, rolling this up sooner than later would be very helpful.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 33: double_message-2449209-33.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

miroslavbanov’s picture

Status: Needs work » Fixed

Moved the patch from #33 to a follow-up #2956916: Follow-up to #2449209, fix double message. Closing this issue as it is done.

hass’s picture

Why are we not committing the bugfix here?

miroslavbanov’s picture

@hass

I don't mind if it's committed in this issue instead of the follow-up issue, but it's now been two months since the patch and it's unfortunately not committed yet. I was contacted by a member of the community to ask for help because he was confused. I created the follow-up issue because I thought it was more clear, and less confusing this way.

hass’s picture

It's more a regression of the previously committed patch. How about committing the follow up and create a new release?

wundo’s picture

I agree with @hass, I'm going to commit it in this issue.

  • wundo committed 7bace11 on 7.x-1.x authored by MiroslavBanov
    Issue #2449209 by MiroslavBanov, Fabianx, vijaycs85, wundo, koppie,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.