google/recaptcha
google/recaptcha is the official PHP client for server-side verification of reCAPTCHA v2 and v3 responses, helping protect forms and APIs from spam and abuse. It supports Composer installation and requires PHP 8+.
with*() builder methods let a single ReCaptcha instance be safely shared as a DI singleton, unblocking or de-risking Laravel Octane, FrankenPHP, RoadRunner, and Swoole migrations. This is a direct enabler for roadmap items around throughput and infrastructure modernization, not just a code-style preference.setScoreThreshold(0.0) no longer bypasses when the API omits score (null), and setChallengeTimeout() no longer passes when challenge_ts is empty or unparseable. For a PM, this converts a silent fraud/abuse gap into a predictable E_SCORE_THRESHOLD_NOT_MET / E_CHALLENGE_TIMEOUT signal that can be alerted on.ReCaptcha::SITE_VERIFY_URL_ALTERNATIVE (www.recaptcha.net) unblocks deployment in regions and enterprise networks where www.google.com is unreachable. This is a go-to-market decision (new geographies, regulated/air-gapped-adjacent customers) that previously required forking or a proxy layer.int $timeout = 60 on CurlPost, Post, and SocketPost, plus CURLOPT_CONNECTTIMEOUT, turns reCAPTCHA latency from a hidden tail-risk into a tunable product parameter. Enables explicit latency budgets on checkout and login flows.submit() calls enables TLS session resumption and HTTP keep-alive, reducing handshake overhead on high-volume forms — measurable in both infra spend and p95 verification latency.Response now implements \JsonSerializable, so verification results can flow directly into structured logs, audit trails, and analytics pipelines without adapters. Unified HTTP 200 validation across all three transports means one consistent failure taxonomy (E_BAD_RESPONSE) regardless of transport choice — far easier to dashboard and alert on.#[\SensitiveParameter] on $secret in ReCaptcha::__construct() and RequestParameters::__construct() prevents credentials leaking into stack traces — directly relevant to SOC 2 / ISO 27001 evidence and SIEM ingestion policies.2.0.0, verified via roave/backward-compatibility-check. This makes the upgrade an operational decision rather than a re-architecture one.Adopt if:
2.x series). If you are already on 2.0.0, adopt 2.1.0 immediately — it is BC and closes two fail-open security bugs.1.x: note this crosses the 2.0.0 boundary, which dropped legacy PHP support. The 2.1.0 release itself is BC with 2.0.0, but your 1.x-to-2.1.0 jump needs a PHP-version audit and a transport review.SITE_VERIFY_URL_ALTERNATIVE is the only supported way to verify where www.google.com is blocked.#[\SensitiveParameter] is a concrete, quotable compliance control.Look elsewhere if:
1.5 means accepting the now-known fail-open behavior in score-threshold and challenge-timeout handling.examples/ as production code. The DOM XSS hardening and action allowlisting in examples/recaptcha-v3-verify.php are informative, but they are still examples — copy the server-side allowlist pattern, not the files."Version 2.1.0 of our reCAPTCHA Laravel package is a security and infrastructure enabler with a clean, backwards-compatible upgrade from 2.0.0. Three things matter commercially:
www.recaptcha.net) removes the blocker for customers and regions where www.google.com is filtered. That turns a "cannot deploy" conversation into a scoping conversation.0.0 or a malformed challenge timestamp could let bot traffic through without failing. These now fail closed. That is direct fraud-loss prevention, and it is now alertable.The migration is a composer update with verified backward compatibility against 2.0.0. The only gating factor is our own PHP version — which is already a prerequisite we have accepted.
Metrics to Track:
E_SCORE_THRESHOLD_NOT_MET and E_CHALLENGE_TIMEOUT responses post-upgrade (expected to rise from zero — those are previously invisible bypasses now surfaced).$secret occurrences in exception logs and error trackers.Ask: Approve a one-sprint upgrade and a short soak period on /checkout and /login. The engineering cost is a single-line Composer bump plus targeted regression tests; the downside of staying on 1.5 is two known fail-open behaviors in our bot defense."*
"2.1.0 is a minor release, 100% backwards-compatible with 2.0.0 (verified via roave/backward-compatibility-check), requiring PHP >=8.4. It hardens the transport layer and fixes two genuine fail-open security bugs.
High-value changes:
withExpectedHostname(), withExpectedApkPackageName(), withExpectedAction(), withScoreThreshold(), and withChallengeTimeout() now clone-and-return instead of mutating. ReCaptcha can be bound as a singleton in Octane, FrankenPHP, RoadRunner, and Swoole without cross-request config bleed. Note: any code relying on mutation side effects must be updated to consume the return value.setScoreThreshold(0.0) previously bypassed when the API omitted score (null). Now returns E_SCORE_THRESHOLD_NOT_MET.setChallengeTimeout() previously failed open on an empty or unparseable challenge_ts. Now returns E_CHALLENGE_TIMEOUT.200 validation across CurlPost (CURLINFO_HTTP_CODE), Post (http_get_last_response_headers() with ignore_errors), and SocketPost, all returning E_BAD_RESPONSE on non-200. SocketPost now loops fwrite() for partial TLS writes and closes handles cleanly on failure.CurlPost lazily initializes and reuses its CurlHandle across submit() calls — TLS session resumption plus HTTP keep-alive. Expect lower p95 and fewer handshakes on high-volume endpoints.int $timeout = 60 on all three transports, plus CURLOPT_CONNECTTIMEOUT on CurlPost. Set these to match your app's request budget, not the default.Response implements \JsonSerializable — pass it straight to json_encode(). Response::fromJson() now filters error-codes to string elements only.#[\SensitiveParameter] on $secret in ReCaptcha::__construct() and RequestParameters::__construct() keeps secrets out of stack traces.examples/recaptcha-v3-verify.php, updated CSP connect-src, and a new examples/recaptcha-v3-immutable.php demonstrating the builder pattern.Migration Plan:
>=8.4; grep the codebase for setScoreThreshold, setChallengeTimeout, setExpectedHostname, setExpectedAction, and setExpectedApkPackageName calls that ignore the return value. Convert to the with*() variants.ReCaptcha in the container as a singleton and derive per-route variants via with*(). Reference examples/recaptcha-v3-immutable.php.$timeout and CURLOPT_CONNECTTIMEOUT in line with your endpoint SLOs.SITE_VERIFY_URL_ALTERNATIVE where www.google.com is blocked; do not make it the default without a network reason.E_SCORE_THRESHOLD_NOT_MET and E_CHALLENGE_TIMEOUT codes to appear in staging. Verify your error mapping and user-facing fallback handle them.composer update google/recaptcha, then prioritize /checkout, /login, and /register.Upgrade note for 1.x users: 2.1.0 is BC with 2.0.0 only. Crossing from 1.5 also means adopting the 2.x PHP >=8.4 floor and its earlier breaking changes; scope the PHP-version and type-safety work as a separate item.
Alternatives Considered:
2.0.0: zero upside, keeps both fail-open bugs.1.5: no PHP 8.4 requirement, but leaves known silent bypasses in bot defense and blocks Octane singleton adoption.Proposal:
'Upgrade to
2.1.0this sprint. It is a Composer bump with verified BC against2.0.0, closes two fail-open security gaps, and unblocks the Octane singleton pattern we flagged as a risk.'*
Call to Action:
"Block half a day: swap mutating setters for the with*() builders, bind ReCaptcha as a singleton, set explicit transport timeouts, and soak on /checkout and /login. Roll out to one high-risk endpoint first and watch for the newly-surfaced E_SCORE_THRESHOLD_NOT_MET and E_CHALLENGE_TIMEOUT codes — they represent abuse that was previously slipping through undetected."
How can I help you explore Laravel packages today?