marshmallow/bot-shield
marshmallow/bot-shield provides lightweight bot protection for Laravel applications. Use configurable middleware and detection rules to identify and block suspicious automated requests, reduce spam, and protect forms and endpoints without complex setup.
Architecture fit. Bot Shield is a Laravel package that hooks into the exception handler pipeline rather than the request lifecycle, which is the right layer for this problem: it classifies why an exception was thrown (forged Livewire payload vs. genuine application defect) and decides whether to report it upstream or convert it into a client error. That is a narrow, well-bounded concern with low blast radius — it does not wrap controllers, middleware, or the Livewire component lifecycle. It assumes a Livewire-based front end and a standard Laravel exception handler; teams not on Livewire get little value from the v1.2.0 additions, since every new rule targets Livewire-specific exception types and payload shapes.
Integration feasibility. Low-to-moderate effort, but the v1.2.0 upgrade path is the dominant cost. Two facts drive this: (1) a published exceptions.rules list replaces the package defaults rather than merging, so every new detector-gated rule in this release is inert on an existing install until someone hand-edits config/bot-shield.php; (2) forged-update detection is on by default via a missing-key-means-true semantic, which is convenient but asymmetric — enabling requires nothing, disabling requires a config edit. Integration is otherwise a composer bump plus a config patch and a re-run of bot-shield:install for greenfield installs.
Technical risk.
ForgedMethodName still lets a genuine typo report; ForgedReactivePropUpdate still reports genuine self-mutation), but the contains-based string matching on error messages is inherently brittle — Laravel/PHP message wording changes across versions could quietly stop matching, or start matching more than intended.ExceptionCondition implementations "must also accept the request," binding the rules to a request-aware contract. Extending this in-house means inheriting that contract's stability.Key questions.
exceptions.rules merging planned, or is replace-not-merge a permanent design decision? If permanent, what is the documented upgrade ritual?contains string matches version-pinned to specific Laravel/Livewire releases, and is there a test matrix covering message-format changes?Stack fit. Laravel + Livewire applications with an existing error-reporting pipeline (Sentry, Flare, Bugsnag, or similar). The package's value is proportional to how much noise forged Livewire payloads currently generate in that pipeline; teams with low exposure or heavy WAF/CDN filtering upstream may find the marginal benefit small relative to the config-maintenance burden.
Migration path. For existing installs the mechanical steps are: bump to v1.2.0, add 'forged_updates' => env('BOT_SHIELD_FORGED_UPDATES', true) to the exceptions block, and append the six new rule entries to the published rules array (two always-true condition-gated rules plus four contains-based error-shape rules). Greenfield installs get everything via bot-shield:install. Note the ordering: forged-update detection is already live after the composer bump, so the upgrade is not a no-op on day one — only the exception-rule additions are opt-in.
Compatibility. Requires the Livewire exception classes named in the release notes (MethodNotFoundException, CannotMutateReactivePropException, plus SupportReactiveProps). Confirm the installed Livewire version exposes them; a class that does not exist in the pinned Livewire version will make the corresponding rule a no-op at best and a config-load error at worst. PHP/Laravel version floors should be checked against the package composer.json before scheduling.
Sequencing.
forged_updates key, deploy with the toggle left at its default. Observe whether forged-update suppression reduces error-tracker volume as expected, and whether any legitimate errors are caught in the net.MethodNotFoundException, CannotMutateReactivePropException). These are the safest additions because they are precisely scoped to forged payloads.contains-based error-shape rules. These are string-matched and the least precise; ship them once step 2's client-error baseline is understood, so any change in error mix is attributable.rules against the application's published config.Maintenance. The recurring cost is config hygiene, not code. Because published rules replace defaults, every future release is a potential silent regression: the package ships a new protection, the application never receives it, and nobody notices until an incident. Mitigate with an explicit upgrade-checklist item and, ideally, a test that asserts the application's rules array contains every rule the package documents as default.
Support. Support burden shifts in a healthy direction — fewer forged-payload alerts reaching on-call — but adds a new failure mode where a real bug stops reporting because a rule over-matched. The contains rules are the likeliest source of "why didn't we see this in Sentry?" questions. Document which exception classes and message fragments are suppressed, and make the config file discoverable to whoever triages missing-error reports.
Scaling. Negligible runtime cost: the work is a handful of string and interface checks inside exception handling, only on the error path. Rule evaluation is linear in the number of rules entries, which will stay small. No new infrastructure, no queue, no storage growth.
Failure modes.
contains rule stops matching, and noise returns; detected by observing alert volume, not by tests unless we add them.ExceptionCondition signature change in a future release breaks in-house conditions at config-load time, which is at least loud.Ramp-up. Low for a developer already fluent in Laravel's exception handler and Livewire internals — perhaps half a day to read the config, trace two or three rules end to end, and understand the condition contract. The conceptual model (detect forged payload → suppress reporting → answer client error) is simple to teach. The harder onboarding is organisational: making sure the platform team knows the published config is the source of truth and that bot-shield:install should not be re-run casually against an already-customised config. Budget a short written runbook covering the upgrade ritual, the toggle, and how to verify a rule is actually firing.
How can I help you explore Laravel packages today?