| Project: | CAPTCHA |
| Version: | 6.x-2.4 |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | Unassigned |
| Status: | needs work |
Issue Summary
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
#1
Can you describe the form where it doesn't work? Is it from Drupal Core? From a contrib module? A custom module?
#2
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.
#3
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?
#4
@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?
#5
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.
#6
I forgot about standard tags field.
#7
I'm afraid is the AJAX stuff. (related issue: #918856: CAPTCHA Session Reuse message on forms with AJAX funcionality (e.g. file upload, add another item, ...))
Can you try without the image field?
#8
I have similar problem with comment form. CAPTCHA fails every time.
But it works properly if remove file and image fields from the form.
#9
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:
<?phplist($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:
<?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);
// set $posted_form_id during the first rendering of the form
$posted_form_id = $this_form_id;
}
?>
To wrap it up:
#10
I'd say this is critical.
Solution #9 works FWIK, so here's a patch.
Please review and commit soon! THX
#11
The last submitted patch, 1024370_Keep_CAPTCHA_from_failing.patch, failed testing.
#12
Solution #9 worked for me.
#13
@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
#14
Oops, something was wrong there. However #13 works fine on our site.
#15
Patch in #13 worked for me.
#16
Patch in #13 worked for me.
#17
Thanks folks, committed.
#18
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
#19
Not fixed in latest 6.x-2.x DEV with Math Captcha added via Form ID to a Mailchimp block...
#20
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?
#21
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']
#22
adding
$element['#tree'] = FALSE;
to the captcha_process function seems to fix this.
Here is a patch for 6.x-2.x-dev.
#24
Committed patch #22 by rocnhorse
http://drupalcode.org/project/captcha.git/commit/2ca5d91
#25
Also committed it on D7 version
http://drupalcode.org/project/captcha.git/commitdiff/538446c3dcf0abdf060...
#26
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"
#27
as mentioned in #26, I reverted the commit of patch #13:
http://drupalcode.org/project/captcha.git/commit/1161a4d
#28
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?
#29
@ skitten6: your problem is probably this: #918856: CAPTCHA Session Reuse message on forms with AJAX funcionality (e.g. file upload, add another item, ...)
#30
this issue should be fixed for Drupal 7 version by http://drupalcode.org/project/captcha.git/commit/ef22105
#31
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.
#32
The last submitted patch, captcha.patch, failed testing.