Undefined array key 2 in Drupal\friendlycaptcha\SiteVerify->verify() when using local endpoint

Created on 18 April 2024, 3 months ago
Updated 2 May 2024, 2 months ago

Problem/Motivation

When using the local endpoint, we get the following error:

Warning: Undefined array key 2 in Drupal\friendlycaptcha\SiteVerify->verify() (Zeile 170 in /web/modules/contrib/friendlycaptcha/src/SiteVerify.php)

Backtrace:

#0 /web/core/includes/bootstrap.inc(164): _drupal_error_handler_real()
#1 /web/modules/contrib/friendlycaptcha/src/SiteVerify.php(170): _drupal_error_handler()
#2 /web/modules/contrib/friendlycaptcha/friendlycaptcha.module(144): Drupal\friendlycaptcha\SiteVerify->verify()
#3 /web/modules/contrib/captcha/captcha.module(522): friendlycaptcha_captcha_validation()
#4 [internal function]: captcha_validate()
#5 /web/core/lib/Drupal/Core/Form/FormValidator.php(282): call_user_func_array()
#6 /web/core/lib/Drupal/Core/Form/FormValidator.php(238): Drupal\Core\Form\FormValidator->doValidateForm()
#7 /web/core/lib/Drupal/Core/Form/FormValidator.php(118): Drupal\Core\Form\FormValidator->doValidateForm()
#8 /web/core/lib/Drupal/Core/Form/FormBuilder.php(593): Drupal\Core\Form\FormValidator->validateForm()
#9 /web/core/lib/Drupal/Core/Form/FormBuilder.php(325): Drupal\Core\Form\FormBuilder->processForm()
#10 /web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm()
#11 [internal function]: Drupal\Core\Controller\FormController->getContentResult()
#12 /web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
#13 /web/core/lib/Drupal/Core/Render/Renderer.php(627): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#14 /web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext()
#15 /web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
#16 /vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#17 /vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
#18 /web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle()
#19 /web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
#20 /web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
#21 /web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\ContentLength->handle()
#22 /web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
#23 /web/core/modules/ban/src/BanMiddleware.php(50): Drupal\page_cache\StackMiddleware\PageCache->handle()
#24 /web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\ban\BanMiddleware->handle()
#25 /web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
#26 /web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
#27 /web/modules/contrib/remove_http_headers/src/StackMiddleware/RemoveHttpHeadersMiddleware.php(49): Drupal\Core\StackMiddleware\AjaxPageState->handle()
#28 /web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\remove_http_headers\StackMiddleware\RemoveHttpHeadersMiddleware->handle()
#29 /web/core/lib/Drupal/Core/DrupalKernel.php(704): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
#30 /web/index.php(19): Drupal\Core\DrupalKernel->handle()
#31 {main}

(Warning)

As a result, the next log entry is:
Signature mismatch. Calculated "a2130a672266a008d8439b5871a405f70a7d042451bf7a7d78303e05ae637c82", given "" (Critical)

I'm unsure what's the result of this.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

🇩🇪Germany Anybody Porta Westfalica

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @Anybody
  • 🇩🇪Germany Anybody Porta Westfalica
  • 🇩🇪Germany jurgenhaas Gottmadingen

    I can't reproduce this.

    What's happening there is that the friendlycaptcha_captcha_validation reads the input with $requestStack->getCurrentRequest()->request->get('frc-captcha-solution') and then explodes that value with this:

    [$signature, $puzzle, $solutions] = explode('.', $solution);
    

    Your error message indicates that the string doesn't contain 3 parts but only 2.

    There is no other operation involved. So, that looks like the request from the browser doesn't send a proper value in frc-captcha-solution, but I don't see how that could be the case. Don't see that this could be related to the local endpoint.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    Do you have the friendly-challenge JS library installed, if so, which version?

    I'm asking, because the request that should contain frc-captcha-solution is generated by that library.

    Do you see any javascript errors in your browser console?

  • 🇩🇪Germany Anybody Porta Westfalica

    Grevil is on it. We're seeing this in a client project. The friendlycaptcha UI is present and working for me.
    Perhaps it happens if JS is disabled, e.g. on crawler access or similar edge cases. We'll provide more information asap.

  • 🇩🇪Germany Grevil

    Yea, I can not reproduce this issue either. If we have JS disabled, The captcha will automatically always fail and a text is displayed to the user, to disable Javascript:

    You need Javascript for CAPTCHA verification to submit this form.
    This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

    I guess this is caused by some kind of bot, or someone trying to break through the captcha and brute force a login.

    But we should fix it nonetheless. On it.

  • 🇩🇪Germany Anybody Porta Westfalica

    Just had a look at the logs and they seem to be regular users, not bots. From different countries, but none of them seems suspicious.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    The MR looks great, except I wouldn't log a critical. Malformed submissions will be negative to the user, but it's not a system failure. I would just log that as info. Anything above warning would trigger an alert in enterprise environments, that's probably not what we want.

  • Issue was unassigned.
  • Status changed to Needs review 3 months ago
  • 🇩🇪Germany Grevil

    Alright, the issue should be fixed now!

    I also just realized another few pain points concerning the logging:

    • We always log any failures as critical, "info" should be enough, as we don't want a bunch of critical log messages inside the log, just because our site is being attacked by bots.
    • We are logging inside verify() and later on again in friendlycaptcha_captcha_validation(). Instead, let's pass a logging message inside returnSolutionInvalid, returnSolutionTimeoutOrDuplicate, returnErrorEmptySolution and returnMalformedSolution to returnResponse, so our returnResponse would look like this: private static function returnResponse(bool $success, string $errorId = NULL, string $error = NULL). Our original "$error" in returnResponse is already an errorId anyway, this way everything is way cleaner.

    I'll create a follow up issue for that.

  • 🇩🇪Germany Grevil

    Created the follow-up issue here: 📌 Adjust the logging for the local endpoint implementation Active .

  • 🇩🇪Germany Grevil

    @jurgenhaas I agree! But I would rather clean that up in the follow-up issue! Hence, there are multiple critical log calls that should be info calls in my opinion:

    Line 179:

    $this->logger->critical('Signature mismatch. Calculated "%calculated", given "%given"', [</li>
            '%calculated' => $calculated,
            '%given' => $signature,
          ]);
    

    Line 187:

    $this->logger->critical('Puzzle "%puzzle" was already successfully used before', ['%puzzle' => $puzzleHex]);
    

    Line 198:

          $this->logger->critical('Puzzle is too old (%age seconds, allowed: %expiry', [
            '%age' => $age,
            '%expiry' => $expiry,
          ]);
    

    Line 212:

    $this->logger->critical('Solution seen in this request before');
    

    Line 221:

    $this->logger->critical($currentSolution . ' (index: ' . $solutionIndex . ') is invalid (' . $first4Int . ' >= ' . $t . ')');
    
  • 🇩🇪Germany jurgenhaas Gottmadingen

    @Grevil sounds good to me.

  • Assigned to Grevil
  • Status changed to Active 3 months ago
  • 🇩🇪Germany Anybody Porta Westfalica

    Thank you all! Agree with both!

    So we fix the error, but don't know about the reason for the root cause yet, right?
    So should we merge this after @jurgenhaas review but leave it open to check the reason? Or what would you suggest?

  • Status changed to RTBC 3 months ago
  • 🇩🇪Germany jurgenhaas Gottmadingen

    Just set to RTBC.

    @Anybody I wouldn't worry about the root too much TBH. I could imagine that the same issue has been there for ages, just that it was invisible since the invalid request went to the remote service and triggered the error there instead of locally. Receiving invalid requests on public URLs seems reasonable, so I would probably close this issue if it were mine.

  • Issue was unassigned.
  • 🇩🇪Germany Grevil

    I would agree with @jurgenhaas, @Anybody should do the final decision here, merging...

    Thanks everyone! :)

    • Grevil committed de5fcad4 on 1.x
      Issue #3441726 by Grevil: Undefined array key 2 in Drupal\...
  • 🇩🇪Germany Grevil

    Let's wait with the release after 📌 Adjust the logging for the local endpoint implementation Active is fixed.

    I'll be right on it after my break!

  • Status changed to Fixed 3 months ago
  • 🇩🇪Germany Anybody Porta Westfalica
  • 🇩🇪Germany Anybody Porta Westfalica

    PS: Unsure if I already offered that, but @jurgenhaas wouldn't it make sense to have you as Co-Maintainer? ;)

  • 🇩🇪Germany jurgenhaas Gottmadingen

    Unsure if I already offered that

    You haven't ;-) but that's no problem. I'm happy to collaborate, regardless of being a co-maintainer or not. Not that I didn't have a lot of modules on my list already. I leave that to you, though.

  • 🇩🇪Germany Anybody Porta Westfalica

    It's out of the question - welcome to the team! :)

  • 🇩🇪Germany jurgenhaas Gottmadingen

    Thank you, happy to be part of the team.

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

Production build 0.69.0 2024