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.

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
StatusFileSize
new325.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
StatusFileSize
new910 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

StatusFileSize
new622 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)