2 years ago, this issue may have been a duplicate. But the fix that was applied to make captcha work for webforms did not ultimately fix the problems that result when using custom ajax on forms that include a captcha field.

In #3, @mcotelo suggests that we can look at the #triggering_element for evidence that an ajax call has been made

In #11, @wodenx demonstrates that we also need to protect the regeneration of the persisted token as the root cause of the the "CAPTCHA session reuse attack detected." error that we receive is due to a mismatch of either token, or (earlier in the logic) a mismatch of actual vs stored form_id.

For me, today, the root cause of the problem is actually line 200 of captcha.module. Here it is in context:

  // Get the CAPTCHA session ID.
  // If there is a submitted form: try to retrieve and reuse the
  // CAPTCHA session ID from the posted data.
  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);
  }

When rebuilding the form, line 199 (that states list($posted_form_id, $posted_captcha_sid) = _captcha_get_posted_captcha_info($element, $form_state, $this_form_id); will return NULL for the form_id. I don't know why. That kind of doesn't make sense.

Original bug report:

I've experienced problems with CAPTCHA 7.x-1.0-beta1 in forms with AJAX: CAPTCHA could never be solved (see http://drupal.org/node/1024370, #9 helped me with that).

Now, in beta2, there is another problem. If a form has AJAX, and you change the element that triggers de AJAX, you get this message: "CAPTCHA session reuse attack detected.".

I've found that _captcha_get_posted_captcha_info() uses $form_state['submitted'] to detect a submitted form. An AJAX 'submitted' form does not have that flag, so I think $form_state['triggering_element'] should be used, instead. Patch is attached.

I had to apply the change in http://drupal.org/node/1024370#comment-4159970 too, but I did not include it in the attached patch, because it breaks other things.

Files: 
CommentFileSizeAuthor
#31 1395184_31.patch1.08 KBcosmicdreams
PASSED: [[SimpleTest]]: [MySQL] 718 pass(es).
[ View ]
#19 captcha.jpg112.27 KBvimalgoradiya
#16 Screenshot Capcha issue 02_07_2012.png42.05 KBvalery86
#15 Screenshot from 2012-06-16 22:54:45.png84.64 KBelvis2
#11 1395184-11-captcha-ajax.patch3.21 KBwodenx
PASSED: [[SimpleTest]]: [MySQL] 731 pass(es).
[ View ]
#3 detect-ajax-form-7.x-1.x-2.patch1.17 KBmcotelo
PASSED: [[SimpleTest]]: [MySQL] 718 pass(es).
[ View ]
captcha-7.x-1.0-beta2-mcotelo.patch848 bytesmcotelo
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch captcha-7.x-1.0-beta2-mcotelo.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

Comments

soxofaan’s picture

Status:Active» Needs review

Status:Needs review» Needs work

The last submitted patch, captcha-7.x-1.0-beta2-mcotelo.patch, failed testing.

mcotelo’s picture

StatusFileSize
new1.17 KB
PASSED: [[SimpleTest]]: [MySQL] 718 pass(es).
[ View ]

Attaching a new patch.

mcotelo’s picture

Status:Needs work» Needs review

Have you tried the last patch I sent?
Is there something I have to do, or something I can help you with?

tomogden’s picture

Status:Needs review» Reviewed & tested by the community

This patch did the trick for me. I have multiple AJAX/AHAH functions going on, which seemed to trigger the 'reuse attack' constantly--until I installed the patch, that is.

Good work!

natuk’s picture

This works for me as well. Thanks.

kernel32ddl’s picture

Not work for me...
After detect-ajax-form-7.x-1.x-2.patch "CAPTCHA session reuse attack detected" has gone, but "The answer you entered for the CAPTCHA was not correct" take place after patch...
And impossible to submit form.

mcotelo’s picture

@kernel32ddl, yes I had that problem too, and I had to apply two changes, the one I posted, and the one in http://drupal.org/node/1024370#comment-4159970

hibersh’s picture

#8 works for me

look to gotta it committed

soxofaan’s picture

wodenx’s picture

Version:7.x-1.0-beta2» 7.x-1.x-dev
Status:Reviewed & tested by the community» Needs review
StatusFileSize
new3.21 KB
PASSED: [[SimpleTest]]: [MySQL] 731 pass(es).
[ View ]

I can confirm that this is not fixed in the latest -dev.

As noted, the patches in #3 and #8 don't seem to be the right solution. The real trouble seems to be that a new captcha token is generated every time the form is rebuilt -- but if the form is being rebuilt as the result of an ajax submission, that new token may well not be sent back with the response, so the next time the form is submitted, the token validation check will fail.

The attached patch fixes this by reusing the existing token if a form is submitted via ajax. I'm not a security expert, though, so I'm not sure what the implications of this are. It seems to me the only alternative is for Captcha to attach a process callback to every form with a captcha, and recursively replace every #ajax callback with one which also sends the new captcha token. Not impossible, but is it worth it?

guy_schneerson’s picture

This patch fixed the problem form me.

santhosh.murugesan’s picture

captcha-7.x-1.0-beta2-mcotelo.patch queued for re-testing.

nbucknor’s picture

patch #11 worked for me as well

elvis2’s picture

StatusFileSize
new84.64 KB

The patch (#11) did not work for me. In my case, I have a form where when the country dropdown is changed, the whole form is refreshed since there are other fields being modified on the form by ajax. I am using 7.x-1.0-beta2+10-dev version.

Attached is a screenshot.

valery86’s picture

Version:7.x-1.x-dev» 7.x-1.0-beta2
StatusFileSize
new42.05 KB

The same as #15 happens to me, "CAPTCHA Session reuse attack detected" when I click on the continent drop-down list.

Screenshot attached with the issue and the modules version.

mpdonadio’s picture

#11 does not work for me (math captcha on AJAXed register form).

patrickavella’s picture

While I don't have much useful info to give, I can confirm that I am getting this bug as well when using it conjunction with http://drupal.org/project/hierarchical_select/

Have any one of the patches been confirmed as the proper approach?

Edit, sorry for the fragmented reply.

The patch in post 11 works to get rid of the captcha warning, but the ajax field that's kicking it off is now giving a "this field is required" error status in the same manner.

Solved for me

I was able to quell the errors that patch 11 left behind by only having one ajax element on the form. If there is a second ajax element (or hierachy select in my case) it tries to validate

vimalgoradiya’s picture

StatusFileSize
new112.27 KB

I am also not recover my error.
While i am using ajax dependant dropdown with captcha (form API).
while populating dropdown it will also return an error.

"CAPTCHA session reuse attack detected."

Stuck.... Stuck.... Stuck....

danielphenry’s picture

Priority:Normal» Major

I'm also seeing the same thing in beta2. I have it on a web form with no ajax loads involved. Captcha is unusable with this bug in place. upping the priority.

Also to note the watchdog listed this:
webform_client_form_14 post blocked by CAPTCHA module: challenge "Image" (by module "image_captcha"), user answered "e55mj", but the solution was "96c966862cf923fb2c9feb7a047327dd".

I of course entered the correct answer in my test so not sure where it's getting this info from.

Edit:
I just realized I do have an ajax file upload so thier is ajax on the form. None the less captcha is unusable for me keeping the priority raised.

sitaram10’s picture

#3: detect-ajax-form-7.x-1.x-2.patch queued for re-testing.

vimalgoradiya’s picture

One antoher solution i found is "ajax callback"
create ajax callback for particular field and this will also refresh captcha image while ajax call.

$form['country'] = array(
'#ajax' => array('event' => 'change', 'callback' => 'modulename_country_callback'),
);

and

function modulename_country_callback($form, $form_state) {
return array(
'#type' => 'ajax',
'#commands' => array(
ajax_command_replace("#stateDiv", render($form['state'])),
ajax_command_replace("#load_captcha", render($form['captcha'])),
)
);
}

here #load_captcha is recall and image is change with ajax of one field is call.

frompasttofuture’s picture

amjad1233’s picture

Can anybody please post the "PATCHED" version of module ?

Regards,
Amjad

warmth’s picture

Any news of the commitment of this patch?

mpdonadio’s picture

I think the issue is that the patches don't seem to work for all cases. I know #11 didn't work for my situation.

becw’s picture

Status:Needs review» Needs work

#11 works in my case, but it seems like the real problem is that captcha is doing validation in the form #process step. Perhaps the session reuse check could be moved from _captcha_get_posted_captcha_info() to captcha_validate()?

In the code it is not clear why so much information is passed through to the front-end form and then retrieved from the front-end form, when it is also stored persistently in the $form_state; if this part of the code isn't clear, I can't effectively patch the bug.

muka’s picture

#11 works for me (on branch 7.x-1.0-beta2)

Liam Morland’s picture

Status:Needs work» Closed (duplicate)
bhavikshah9’s picture

Issue summary:View changes

#3 worked for me. Also, i didn't faced the problem mentioned in #7.

cosmicdreams’s picture

Status:Closed (duplicate)» Needs review
StatusFileSize
new1.08 KB
PASSED: [[SimpleTest]]: [MySQL] 718 pass(es).
[ View ]

2 years ago, this issue may have been a duplicate. But the fix that was applied to make captcha work for webforms did not ultimately fix the problems that result when using custom ajax on forms that include a captcha field.

In #3, @mcotelo suggests that we can look at the #triggering_element for evidence that an ajax call has been made

In #11, @wodenx demonstrates that we also need to protect the regeneration of the persisted token as the root cause of the the "CAPTCHA session reuse attack detected." error that we receive is due to a mismatch of either token, or (earlier in the logic) a mismatch of actual vs stored form_id.

For me, today, the root cause of the problem is actually line 200 of captcha.module. Here it is in context:

  // Get the CAPTCHA session ID.
  // If there is a submitted form: try to retrieve and reuse the
  // CAPTCHA session ID from the posted data.
  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);
  }

When rebuilding the form, line 199 (that states list($posted_form_id, $posted_captcha_sid) = _captcha_get_posted_captcha_info($element, $form_state, $this_form_id); will return NULL for the form_id. I don't know why. That kind of doesn't make sense.

So here's a quick work around that fixes this bug for me.

Note: instead of using the triggering_element like #3 does, I'm checking to see if there is any rebuild info. I like this patch better than #11, because it's cleaner / reuses more of the existing logic / is smaller.

Let me know what you think.

(see attached)

cosmicdreams’s picture

Issue summary:View changes
cosmicdreams’s picture

Issue summary:View changes
tko’s picture

#31 solves my issue with captcha on forms with multiple field values where 'add new item' and 'remove' were triggering session resuse errors.