Frequently asked questions
What is darvis/livewire-injection-stopper?
A Laravel package for applications that use Livewire. Its middleware rejects requests from listed User-Agents and IP addresses and Livewire update requests that send an array to a property that looks scalar. It also keeps two bot-driven Livewire exceptions out of error tracking and has an artisan command that lists public properties that probably need #[Locked].
How do I block scripted bots in a Laravel Livewire application?
Run composer require darvis/livewire-injection-stopper. The middleware joins the web group by itself and rejects User-Agents that contain a listed pattern such as python, curl/, wget or go-http-client, plus the exact IP addresses you list. Routes outside the web group are only covered when you add the livewire-injection-stopper middleware alias to them.
Which PHP, Laravel and Livewire versions does it support, and what does it cost?
PHP 8.2 or higher, Laravel 11, 12 or 13, and Livewire 3 or 4. It is free and open source under the MIT license, and it needs no account, API key or external service.
Can a bot get around it, and is it a replacement for a firewall?
Yes, a bot can get around it, and no, it is not a firewall. A client that sends a browser User-Agent or no User-Agent passes the User-Agent check, scalar values are never inspected, and arrays under a nested key such as form.tags pass. Combine it with #[Locked] properties, validation, rate limiting and a honeypot on forms.
Will it block Googlebot or other search engines?
Not with the default settings. The default list names specific HTTP clients and SEO and AI crawlers (AhrefsBot, SemrushBot, GPTBot, ClaudeBot and others) and holds no generic word like bot or crawler. If you add such a word yourself, put the search engines and your uptime monitor in allowed_user_agents first.
Why does Sentry keep reporting CannotUpdateLockedPropertyException in my Livewire app?
Livewire throws that exception whenever a request tries to change a #[Locked] property, which replayed and manipulated requests do. The package marks it as not reportable on Laravel’s exception handler, answers the request with the block response (403 by default) and dispatches a RequestBlocked event. A handler that overrides report() and calls Sentry directly needs an early return with SilentExceptionHandler::shouldSilence($e).
My Livewire multi-select or checkbox group returns Access Denied after installing the package. Why?
With block_all_array_injections enabled (the default), every array sent to a top-level Livewire property is rejected. Bind the array under a nested key such as form.tags, or set that option to false so only the names in scalar_properties and the fixed prefixes such as is_ and show_ are checked.
How do I find Livewire properties that should be #[Locked]?
Run php artisan livewire-injection-stopper:audit. It scans app/Livewire and app/Traits for public bool, int, string or nullable class properties with a default value that lack #[Locked] on the line above and whose name or type looks sensitive (admin, role, permission, max, limit, user, cart and more). It exits with code 1 when it flags something, and it is a text scan, so a clean result is not proof.
How do I log or count blocked requests?
Listen for Darvis\LivewireInjectionStopper\Events\RequestBlocked. It carries the reason (blocked_ip, blocked_user_agent, suspicious_payload or locked_property), the ip, the userAgent, the url and, for silenced exceptions, the exception. A warning that starts with [LivewireInjectionStopper] is also written to the log unless log_blocked_requests is false.
How is it different from darvis/livewire-honeypot?
They do different jobs. darvis/livewire-honeypot adds a honeypot field and a time trap to forms. This package works on the request itself, with User-Agent and IP checks and an inspection of Livewire update payloads, and it audits components for unlocked properties. It uses no JavaScript, no cookies and no external service.