CAPTCHA started to behave strange today. It is working OK on most forms, but one. A that specific form it always blocks, saying, that provided solution was not correct (but it is!). After some debugging I found out, that captcha generates a new CAPTCHA session before checking existing one. "Old" solution then fails with new session.

While researching the problem, I found the problem in captcha_element_process():

<?php
  list($posted_form_id, $posted_captcha_sid) = _captcha_get_posted_captcha_info($element, $form_state, $this_form_id);
  if ($this_form_id == $posted_form_id && isset($posted_captcha_sid)) {
    $captcha_sid = $posted_captcha_sid;
  }
  else {
    // Generate a new CAPTCHA session if we could not reuse one from a posted form.
    $captcha_sid = _captcha_generate_captcha_session($this_form_id, CAPTCHA_STATUS_UNSOLVED);
  }
....
?>

it seems like _captcha_get_posted_captcha_info() returns NULL for $posted_form_id. I went down to this function and found out that problem lies in previously determined form and captcha ID, since $form_state['captcha_info']['form_id'] is NULL.

<?php
  if (isset($form_state['captcha_info'])) {
    // We already determined the posted form ID and CAPTCHA session ID
    // for this form, so we reuse this info
    $posted_form_id = $form_state['captcha_info']['form_id'];
    $posted_captcha_sid = $form_state['captcha_info']['captcha_sid'];
  }
  else {
    // We have to determine the posted form ID and CAPTCHA session ID
    // from the post data.
    // TODO: is this enough? We had to check more sources in Drupal 6 (see over there).
......
?>

If I baypass prevously determined ID

<?php
  if (FALSE) {
    // We already determined the posted form ID and CAPTCHA session ID
    // for this form, so we reuse this info
    $posted_form_id = $form_state['captcha_info']['form_id'];
    $posted_captcha_sid = $form_state['captcha_info']['captcha_sid'];
  }
  else {
    // We have to determine the posted form ID and CAPTCHA session ID
    // from the post data.
    // TODO: is this enough? We had to check more sources in Drupal 6 (see over there).
......
?>

CAPTCHA works fine. I have not found the reason for $form_state['captcha_info']['form_id'] being NULL.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

soxofaan’s picture

It is working OK on most forms, but one.

Can you describe the form where it doesn't work? Is it from Drupal Core? From a contrib module? A custom module?

slashrsm’s picture

It is a node-edit form. I have a content type, that can be added by anonymous user and then checked and published by editor. Since form is open to the internet i use CAPTCHA to protect it.

chadd’s picture

i also have captcha (both the default math and reCaptcha) failing every time, but only on a form built with a custom module.
drupal v6.20
captcha 6.x-2.3

this just started happening since the upgrade to 6.20
did something change with 6.20's forms API?

soxofaan’s picture

@chadd: please open a separate issue, this issue is about CAPTCHA 7.x-1.x

@slashrsm: what kind of fields are on the node type? Is there perhaps any AJAX involved?

slashrsm’s picture

There are Title, Body, 3 text fields and image field. Latter uploads images over AJAX, AFAIK.

It is this form.

http://pogledi.si/node/add/pisma-bralcev

It works now because of fix from Description of this issue.

slashrsm’s picture

I forgot about standard tags field.

soxofaan’s picture

I'm afraid is the AJAX stuff. (related issue: #918856: CAPTCHA Session Reuse message on webforms )
Can you try without the image field?

Chi’s picture

Priority: Normal » Major

I have similar problem with comment form. CAPTCHA fails every time.
But it works properly if remove file and image fields from the form.

nineLemon’s picture

I ran into the very same problem while having an ajax powered form rendered into a block. After hours of debugging I came to the same conclusion as slashrsm, but I found a different solution:

Find the following lines in the captcha_element_process function:

  list($posted_form_id, $posted_captcha_sid) = _captcha_get_posted_captcha_info($element, $form_state, $this_form_id);
  if ($this_form_id == $posted_form_id && isset($posted_captcha_sid)) {
    $captcha_sid = $posted_captcha_sid;
  }
  else {
    // Generate a new CAPTCHA session if we could not reuse one from a posted form.
    $captcha_sid = _captcha_generate_captcha_session($this_form_id, CAPTCHA_STATUS_UNSOLVED);     
  }              

and change it to:

  list($posted_form_id, $posted_captcha_sid) = _captcha_get_posted_captcha_info($element, $form_state, $this_form_id);
  if ($this_form_id == $posted_form_id && isset($posted_captcha_sid)) {
    $captcha_sid = $posted_captcha_sid;
  }
  else {
    // Generate a new CAPTCHA session if we could not reuse one from a posted form.
    $captcha_sid = _captcha_generate_captcha_session($this_form_id, CAPTCHA_STATUS_UNSOLVED);  
    
    // set $posted_form_id during the first rendering of the form
    $posted_form_id = $this_form_id; 
  }              

To wrap it up:

  1. set $posted_form_id during initial form render
  2. the hidden field "form_id" will be set with this value
  3. after submitting the form $form_state['captcha_info']['form_id'] will have the form_id stored
  4. ($this_form_id == $posted_form_id) will be true, thus $captcha_sid will stay the same
  5. captcha validation should now be fine
Pancho’s picture

Version: 7.x-1.0-alpha2 » 7.x-1.x-dev
Priority: Major » Critical
Status: Active » Needs review
FileSize
325.81 KB

I'd say this is critical.
Solution #9 works FWIK, so here's a patch.
Please review and commit soon! THX

Status: Needs review » Needs work

The last submitted patch, 1024370_Keep_CAPTCHA_from_failing.patch, failed testing.

postscripter’s picture

Status: Needs work » Fixed

Solution #9 worked for me.

soxofaan’s picture

Status: Fixed » Needs review
FileSize
910 bytes

@postscripter: please don't flag this issue as fixed, as long as the fix is not committed yet
@pancho in #10: There is something wrong with your patch: it also contains the removal of all translation files, but those are already removed.

In attachment the reworked patch from #10

Pancho’s picture

Oops, something was wrong there. However #13 works fine on our site.

Chi’s picture

Status: Needs review » Reviewed & tested by the community

Patch in #13 worked for me.

e5sego’s picture

Patch in #13 worked for me.

wundo’s picture

Status: Reviewed & tested by the community » Fixed

Thanks folks, committed.

valderama’s picture

fyi: this patch is not applied in 7.x-1.0-alpha3; for now either use the dev version or add the change to the alpha3 version..

and another info, this patch solved the issue that the captcha on a user-register form always failed..

greets,
walter

Jim Kirkpatrick’s picture

Version: 7.x-1.x-dev » 6.x-2.x-dev
Status: Fixed » Patch (to be ported)

Not fixed in latest 6.x-2.x DEV with Math Captcha added via Form ID to a Mailchimp block...

jorisdv’s picture

I am currently stuck on the same problem (Drupal 6.20, Captcha 6.x-2.4). the proposed solutions did not work... Did anyone get captcha to work in a mailchimp form?

rocnhorse’s picture

It looks like the problem is #tree=true.

With #tree=true, $form_state['values']['captcha_response'] doesn't exist it's something like $form_state['values']['captcha']['captcha_widgets']['captcha_response']

rocnhorse’s picture

FileSize
622 bytes

adding
$element['#tree'] = FALSE;
to the captcha_process function seems to fix this.

Here is a patch for 6.x-2.x-dev.

soxofaan’s picture

soxofaan’s picture

soxofaan’s picture

commit of patch #13 by #17 should be reverted.
$posted_form_id = $this_form_id makes no sense: there could be multiple forms on same page, but there can only one be posted.

It also breaks things: #1328272: "10 more examples of this challenge"

soxofaan’s picture

Status: Patch (to be ported) » Needs work

as mentioned in #26, I reverted the commit of patch #13:
http://drupalcode.org/project/captcha.git/commit/1161a4d

skitten6’s picture

Version: 6.x-2.x-dev » 7.x-1.0-beta1

I seem to have the same problem. when i remove the extra image field the problem is fix. But since im new with drupal codes, im not really sure how to fix this problem with the patch. Maybe a different or easier way for newbies to fix this problem?

soxofaan’s picture

Version: 7.x-1.0-beta1 » 6.x-2.x-dev

@ skitten6: your problem is probably this: #918856: CAPTCHA Session Reuse message on webforms

soxofaan’s picture

this issue should be fixed for Drupal 7 version by http://drupalcode.org/project/captcha.git/commit/ef22105

tommeir’s picture

Version: 6.x-2.x-dev » 6.x-2.4
Status: Needs work » Reviewed & tested by the community

testing #22 + #13 against captcha 6.x - 2.4.

anonymous mailchimp works :)

thank you guys. you are a life saver.

btw - changing versions from 2.4 to 2.dev result in empty settings form in the captcha settings. even if you try to add forms to it.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, captcha.patch, failed testing.

danisha’s picture

The issue is not fixed.

https://www.drupal.org/node/2233569#comment-12339687

Can someone help?

Anonymous’s picture

I have the same Issue, Drupal 7.34 and Zen Theme

Did anyone get any fix for it?

wundo’s picture

Status: Needs work » Closed (outdated)