Repository navigation
Verify reCAPTCHA tokens over cURL instead of file_get_contents (magento/magento2#41428) - #347
lbajsarowicz wants to merge 1 commit into
Conversation
Magento\ReCaptchaValidation\Model\ReCaptcha was created without a request method, so the library fell back to RequestMethod\Post, which calls file_get_contents() on the siteverify URL. On servers with allow_url_fopen=0 every verification failed with connection-failed and reCAPTCHA-protected forms rejected all submissions. Inject ReCaptcha\RequestMethod\CurlPost through di.xml. ext-curl is already required by magento/framework; it is now declared by the module too.
|
@magento run all tests |
|
@alzota tracked in magento/magento2#41428 (internal AC-19076). Happy to adjust anything if the team prefers a different approach, for example a bounded cURL timeout. |
|
Tested on Magento Open Source 2.4.9 (magento/module-re-captcha-validation 1.1.5, phpfui/recaptcha 2.0.1, PHP 8.5), calling
So with Confirming the fix works as described. It would be good to see this reviewed, since it affects every reCAPTCHA-protected form on hardened hosting. |
Description (*)
Magento\ReCaptchaValidation\Model\ReCaptchais created byValidator::isValid()with only the secret, soReCaptcha\ReCaptcha::__construct()falls back toRequestMethod\Post. That class verifies the token withfile_get_contents()onhttps://www.google.com/recaptcha/api/siteverify. On servers running withallow_url_fopen=0the call fails, the library returnsconnection-failed, and every reCAPTCHA-protected form rejects every submission.This PR injects
ReCaptcha\RequestMethod\CurlPost(shipped byphpfui/recaptcha, no required constructor arguments) through the module'sdi.xml. cURL works regardless ofallow_url_fopen, andext-curlis already required bymagento/framework; the module now declares it in its owncomposer.jsonas well.Because one validator serves storefront, admin, REST and GraphQL, the change covers every reCAPTCHA entry point.
An integration test asserts that
ReCaptchaFactoryproduces an instance that usesCurlPost.Fixed Issues (if relevant)
Manual testing scenarios (*)
allow_url_fopen = Offfor PHP-FPM.file_get_contents(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0.I also checked it outside a full installation: I parsed this module's
di.xmlwithMagento\Framework\ObjectManager\Config\Mapper\Dom, builtMagento\ReCaptchaValidation\Model\ReCaptchathrough the ObjectManager, and calledverify()underphp -d allow_url_fopen=0. Without thedi.xmlentry it usedPostand returnedconnection-failed. With it,CurlPostreached Google, which returnedinvalid-input-responsefor the dummy token.Questions or comments
Postis bounded bydefault_socket_timeout, whileCurlPostuses cURL defaults with no total timeout. If a bounded timeout is wanted, it can be added in a follow-up through a customReCaptcha\RequestMethod\Curlwrapper.Contribution checklist (*)