Search by

nickdekruijk / laravel-bot-noise

nickdekruijk

Keeps bot traffic out of your Laravel error tracking: filters Livewire probe exceptions, refuses arrays sent to non-array properties and cleans invalid UTF-8 from the query string

Package info

github.com/nickdekruijk/laravel-bot-noise

pkg:composer/nickdekruijk/laravel-bot-noise

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-11-05 15:47 UTC

This package is auto-updated.

Last update: 2026-11-05 15:50:44 UTC


README

Scanners probe every public Livewire endpoint. Each probe ends up as an exception in your error tracker, and on a small plan they eat your quota. This package keeps that traffic out, in one place instead of per project.

It is auto-discovered, so installing it is all you need to do:

composer require nickdekruijk/laravel-bot-noise

It needs no Sentry and no Livewire. It works through Laravel's exception handler, so laravel.log stays clean too and any error tracker benefits.

What it does

Filters exceptions

Only in the environments from the config, by default production. A real bug still shows up on staging.

Exception Reason
CorruptComponentPayloadException a tampered snapshot
CannotUpdateLockedPropertyException an attempt to overwrite a locked property
MissingFileUploadsTraitException an upload call to a component without uploads
MethodNotFoundException for _xNonExist a method name scanners try. Other missing methods stay reported on Livewire versions that report them
ErrorException "array offset on null" from Livewire's HandleComponents a payload without a snapshot
ErrorException "Input variable nesting level exceeded" a query string nested too deep
TypeError "Cannot assign array to property" raised inside Livewire an array sent to a typed property

The rules on the content of an exception look at where it came from. The same warning in your own code is a bug and stays reported.

Recent Livewire versions stay silent on some of these by themselves when app.debug is off. This package covers the older versions and the exceptions Livewire still reports.

Refuses arrays for properties that don't take one

A Livewire update that sends an array to a top-level property gets a 403, unless the property holds an array or object right now, or its type accepts one (array, iterable, mixed, object or a class). Nested paths like form.tags are left alone.

This matters most for untyped properties. public $license; has no protection of its own, and the array ends up in your code. A typed scalar like public string $license already refuses it with a TypeError, that now becomes a 403.

A refusal is logged at info level with the component and property, never the value. The guard runs in every environment, so a conflict shows up during development.

If a property really needs to receive an array while it is empty, give it the type array, or a default of [], or add it to array_guard_except.

Cleans the query string

Invalid UTF-8 like ?q=%E9 is replaced, in nested values too. Otherwise the bytes can reach json_encode, for example in a Livewire snapshot, and the page crashes with a 500. This also runs in every environment, because it prevents an error instead of hiding one.

Configuration

php artisan vendor:publish --tag=bot-noise-config
Key Default
enabled env('BOT_NOISE_ENABLED', true) master switch, use it to see everything again during an incident
environments ['production'] where the exception filter runs
sanitize_query_string true
array_guard true
array_guard_except [] properties as 'component.property'

What it does not do

It blocks nothing at the door and bans no one, and a filter is no protection. Keep Livewire up to date, and look at your access logs when you want to know what scanners are doing.

Tests

composer install
vendor/bin/phpunit

License

MIT, see LICENSE.md.