Problem/Motivation

During a security audit we see that we can pass through the math captcha, so people can by example create a lot of account in user/register without problems.

Steps to reproduce

- last Drupal 11.x
- last captcha 2.0.9

- captcha math enabled on register form
- settings persistance "Always add a challenge."
- fill manually the user/register form a first time, capture the submission as a curl request with your browser, in my case , it was:

curl --location 'http://drupal.docker.localhost:8000/user/register' \
--header 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
--header 'Accept-Language: fr-FR,fr;q=0.9' \
--header 'Cache-Control: no-cache' \
--header 'Connection: keep-alive' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Origin: http://drupal.docker.localhost:8000' \
--header 'Pragma: no-cache' \
--header 'Referer: http://drupal.docker.localhost:8000/user/register' \
--header 'Sec-Fetch-Dest: document' \
--header 'Sec-Fetch-Mode: navigate' \
--header 'Sec-Fetch-Site: same-origin' \
--header 'Sec-Fetch-User: ?1' \
--header 'Upgrade-Insecure-Requests: 1' \
--header 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36' \
--header 'sec-ch-ua: "Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"' \
--header 'sec-ch-ua-mobile: ?0' \
--header 'sec-ch-ua-platform: "Linux"' \
--data-urlencode 'mail=myemail@mail.fr' \
--data-urlencode 'name=myemail@mail.fr' \
--data-urlencode 'form_build_id=form-jXfnUG_wp4F9U-TxiWldEBP7wbu10dBTbnH--otV7tc' \
--data-urlencode 'form_id=user_register_form' \
--data-urlencode 'captcha_sid=5' \
--data-urlencode 'captcha_token=E-h0TOLXtWXUpelA5BM9FqPPOnQ9cFtzpqj0yXclvek' \
--data-urlencode 'captcha_response=8' \
--data-urlencode 'op=Create new account' 

- change the email in the curl request, here myemail@mail.fr by myemail2@mail.fr , launch several times the request, the captcha will be valid ramdomly if you put a response between 1 and 20 (here i let 8) . Maybe first time or after 15-30 trys.

Proposed resolution

Avoid that a captcha response can be replayed, use a one time captcha token ?

Issue fork captcha-3558256

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

tichris59 created an issue. See original summary.

tichris59’s picture

Issue summary: View changes
tichris59’s picture

Issue summary: View changes

pablonicolas made their first commit to this issue’s fork.

joevagyok made their first commit to this issue’s fork.

grevil’s picture

Version: 2.0.9 » 2.x-dev

Test LGTM! Other failing tests are unrelated. I created a separate issue for this: #3567905: Fix failing tests.

The test here suggests, that we should delete the token after captcha_validate() is called. Although this is the most secure approach and will definitely resolve this issue, it will probably cause some UX Issues:

  1. The user registers and has a typo in the "confirm password" input => The form displays an error and the user has to redo the captcha.
  2. An impatient user double clicks a form submit button => After the first request, the second thows an error because the token is gone.

@japerry should decide, if and how this should be fixed.

anybody’s picture

Unsure if this is really critical, as Math Captcha is kind of "funny" in times of AI (and even before it was more kind of a demo level).

grevil’s picture

Priority: Critical » Major

@anybody, even though Captcha Math is mentioned here, I think it also applys to other captcha types (the failing test also uses captcha type "test" not "math").

But I still agree I don't see it as "Critical", as the user has to at least get the captcha correct once. He can't get around the captcha entirely.

grevil’s picture

Regarding the UX issues in #7, after these issues are confirmed, we could also make a setting out of this, e.g. ("Delete captcha token after validation", Default TRUE).

We should also check what the behavior is with the multistep form captcha validation turned on.

alexboss’s picture

Dear maintainers / developers,

Thank you for your feedback and considering fixing the issue.

Indeed, there are some constraints, but can´t they be overcome ? For instance:

The user registers and has a typo in the "confirm password" input => The form displays an error and the user has to redo the captcha.

Not really an issue IMHO, this happens rarely, and even if it does, it´s already the case on many registration / contact forms.

An impatient user double clicks a form submit button => After the first request, the second thows an error because the token is gone.

Isn´t possible to disable the submit button once it has been submitted once or a validation process is ongoing ? Plus, if it has been submitted at least once (first request) and went through successfully, then it´s fine.

But I still agree I don't see it as "Critical", as the user has to at least get the captcha correct once. He can´t get around the captcha entirely.

Yes, that´s true. But the problem observed is that once a form has been submitted with a valid captcha, then it's really easy to copy the submission as a cURL request and litterally flood / spam the contact forms with hundred of automated submissions. This should be prevented.

Thank you and best regards.

joevagyok’s picture

Any captcha method can be skipped with this, not only Math Captcha.

joevagyok’s picture

Status: Active » Needs review
anybody’s picture

Nice @joevagyok that looks clever. We should fix #3567905: Fix failing tests first I think to see real test results here?

grevil’s picture

Agreed. especially since the "max PHP" and "next minor" pipelines now fail compared to the pipelines in #3567905: Fix failing tests.

Unfortunately the tests are probably not fixed in a few minutes...

alexboss’s picture

Thanks @joevagyok for the fix https://git.drupalcode.org/project/captcha/-/merge_requests/124/diffs?co...

Having tested on my ends, it completely blocks the recording of submissions using cURL / session replay attacks.

Amazing job, thanks !

joevagyok’s picture

The failing tests issue is green now. Please review it so we can move this forward!

anybody’s picture

Status: Needs review » Reviewed & tested by the community

RTBC once tests are green

anybody’s picture

Status: Reviewed & tested by the community » Needs work

While tests are now green in #3567905: Fix failing tests it's still failing here.

grevil’s picture

Title: Security: the math CAPTCHA can be replayed » Security: Any CAPTCHA can be replayed
joevagyok’s picture

Status: Needs work » Needs review
anybody’s picture

Thanks @joevagyok!!

grevil’s picture

Status: Needs review » Reviewed & tested by the community

Just some textual changes to the comments. Otherwise this LGTM!

grevil’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

grevil’s picture

Thanks everyone, I tagged a new release: https://www.drupal.org/project/captcha/releases/2.0.10.

Status: Fixed » Closed (fixed)

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