jakreiter/recaptcha2-bundle-proxyable
A Symfony/PHP bundle that integrates Google reCAPTCHA v2 and adds proxy support for verification requests. Configure keys, render the widget, and validate form submissions through a proxy when required, making spam protection easier to deploy in restricted network environments.
Architecture fit. Poor as packaged. Despite the task framing, this is a Symfony bundle, not a Laravel package. It ships a Bundle subclass, a DependencyInjection extension with a Configuration tree, and presumably a form type / Twig extension — all bound to Symfony's kernel and container lifecycle. Laravel's Illuminate container does not process Bundle::build() or Extension::load(); there is no auto-discovery for config/bundles.php equivalents. Anything reusable here is the verification client buried inside the bundle wiring, not the bundle itself. The proxy capability is explicitly marked "in progress," which puts the one differentiated feature on the wrong side of stable.
Integration feasibility. Feasible only via extraction. The underlying work is small — build a verify($token, $ip) call against https://www.google.com/recaptcha/api/siteverify, POSTing secret, response, remoteip, and route it through an HTTP client with a proxy option. Guzzle and Laravel's Http facade both expose proxy (including socks5 and per-scheme auth), so the capability is a one-line option, not a reason to adopt a dependency. Practical path: install google/recaptcha (official, PSR-18 injectable) or hand-roll ~150 lines, and wrap it in a Laravel service provider + FormRequest rule. Pulling in a 0-star Symfony bundle to obtain a Guzzle option is net-negative value.
Technical risk. Several compounding items:
| Risk | Severity | Note |
|---|---|---|
| Zero stars, zero dependents, single maintainer fork | High | No signal that security fixes land; verification is a security control, not a utility |
| "in progress" proxy feature | High | Exact code path you need is unfinished; you would be its only tester |
| LGPL-3.0 | Medium | Usable in closed-source PHP apps, but forking/vendoring creates relinking and source-availability obligations; needs legal sign-off, not a TPM call |
| Symfony coupling | Medium | Bundle wiring is dead weight; you'd strip it, i.e., maintain a fork |
| Egress via proxy to a security endpoint | Medium | Secret and client IP traverse the proxy hop; TLS termination at the proxy is a credential-exposure vector |
Key questions.
CONNECT tunneling is acceptable or you're leaking secrets to an inspecting proxy.siteverify times out? For a registration form, fail-closed blocks revenue; fail-open disables the control. This is a product decision, not a library one.Verdict: Do not adopt. Score (opportunity 24.46, 0 stars, 0 dependents) matches the technical read: the capability is trivial to reproduce in-house, and the package carries security-surface and license risk disproportionate to its value.
Stack fit. Laravel-native equivalent is a four-piece build, none of which requires Symfony:
config/services.php → recaptcha.site_key, secret, verify_url, proxy (from .env, null in local).App\Services\Recaptcha\Verifier → constructor-injected Illuminate\Http\Client\Factory, calls Http::asForm()->withOptions(['proxy' => $proxy, 'timeout' => 3, 'connect_timeout' => 2])->post(...), returns a typed result object (success, score/error codes, latency, degraded flag).Rules\ValidRecaptcha / RecaptchaRequest → validation layer, so call sites stay declarative.@recaptchaScripts directive; site key from config so environments don't cross-wire.If legal insists on the LGPL path, the fallback is: composer require jakreiter/recaptcha2-bundle-proxyable, do not register the bundle, and use only the verifier class via a manual binding — but verify first that the class has no container-trait dependencies.
Migration path. Nothing to migrate from if reCAPTCHA isn't live yet. If a prior Laravel app used greggilbert/recaptcha or inline file_get_contents calls, replace them behind the new Verifier interface in one PR and delete the old clients; keep the interface stable so the swap is invisible to controllers.
Compatibility. Confirm composer.json PHP and symfony/* constraints before any spike — a bundle pinned to Symfony 7 / PHP 8.2+ will conflict with an older Laravel 10 app on PHP 8.1. Laravel 10–12 and PHP 8.1–8.4 are safe for the in-house build. Proxy support in Guzzle requires curl ext; verify the proxy honors HTTPS_PROXY/NO_PROXY so the same image works in dev and prod.
Sequencing.
siteverify reachability. This answers the only question the package could have answered.Http::fake() suite so CI needs no network.Maintenance. In-house: ~200 LOC plus tests, owned by the team that owns the form. Adopting the bundle: you inherit an unmaintained fork, so you are de facto the maintainer of a security dependency with no upstream you control (upstream Beelab is the real project; this fork's release date reflects fork activity, not a support commitment). Net, the build option is lower total cost of ownership from month two onward.
Support. No vendor, no SLA, no issue triage on a 0-star fork. The one thing you'd want supported — a proxy regression — is exactly the part labeled "in progress." Budget on-call ownership explicitly; reCAPTCHA failures page someone.
Scaling. Verification adds one outbound HTTPS round trip per submission (~100–300ms via a healthy proxy). Volume is low relative to typical form traffic, but three things scale badly:
Failure modes. Enumerate and instrument these up front:
.env/secret manager must rotate without redeploy drift.connect_timeout, a hung proxy stalls PHP-FPM workers and cascades into an availability incident.degraded=true rate > 0 for more than N minutes.Ramp-up. Low for the build path: the team already operates Laravel's HTTP client, service container, and validation; the only new concepts are Google's response codes and proxy semantics. The Symfony-bundle path inverts this — the team would need Symfony bundle internals to debug wiring, for zero product benefit. Expected ramp: a mid-level engineer ships and tests the in-house verifier in 2–3 days; a junior can then add it to a new form in under an hour once the Blade component and rule exist.
How can I help you explore Laravel packages today?