Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Scanner Guard Laravel Package

jeffersongoncalves/filament-scanner-guard

Protect your Filament admin panel from automated vulnerability scanners. Scanner Guard detects suspicious scan attempts, logs malicious traffic, and blocks it before it reaches sensitive routes, with simple configuration and a native Filament settings page for managing rules.

View on GitHub
Deep Wiki
Context7

Getting Started

This release (1.2.0) is a maintenance bump — no breaking changes, no new public API, no config or migration changes. The two things worth knowing:

  • Runtime fix: purging or unbanning records no longer wipes the bans-per-day chart history.
  • Tooling: the dev dependency now allows orchestra/testbench ^10.0 || ^11.0, and the CI tests workflow was standardized. Neither affects your application — testbench 11 is the Laravel 12 test harness, so the package's own suite now runs on both.

If you are already on 1.1.x, composer update jeffersongoncalves/filament-scanner-guard is safe. There is nothing to republish and no migration to run.

Fresh install:

  1. composer require jeffersongoncalves/filament-scanner-guard
  2. Publish and review the config (vendor:publish --tag="filament-scanner-guard-config") — this is the file you will actually spend time in.
  3. Run migrations (php artisan migrate). The package stores ban/hit records in your own database, so the tables land in your app schema.
  4. Register the plugin on the panel in your PanelProvider: ->plugin(ScannerGuardPlugin::make()).
  5. Clear cached config after any change: php artisan config:clear.

Look first at: the config file (allowlists, blocked patterns, retention), then the middleware registration in your HTTP kernel/bootstrap/app.php, then the Filament resource for bans in the admin panel.

First realistic use case: let the package watch for the usual noise — /wp-login.php, /.env, /phpmyadmin, /.git/config — and review the resulting bans in the admin UI before you turn on any automatic enforcement. Watch the bans-per-day widget for a week to confirm you are catching scanners and not your own monitoring or health-check traffic.

Implementation Patterns

Start in observation mode, not enforcement. Most painful rollouts happen when the guard is set to block on day one. Log/record first, confirm the allowlist is right, then switch the enforcement flag in config.

Allowlist aggressively and explicitly. Internal RFC1918 ranges, your uptime/monitoring providers, your office egress IPs, your CI runner IPs, and any partner doing bulk API calls. Keep the allowlist in config (not in the DB) so it is version controlled.

Handle proxied traffic properly. The guard bans the IP it sees. Behind Cloudflare or a load balancer, that is your proxy's IP unless TrustProxies is configured — meaning one bad actor bans everyone, or you ban your own CDN. Fix TrustProxies before enabling blocking.

Pair with a scheduled prune. Set retention in config and schedule the prune command; the 1.2.0 chart fix means pruning no longer destroys your trend line, so you can now set a short retention (30–90 days) without losing the visual history.

Use the unban action as an operational workflow. When a legitimate user reports a block, unban from the resource, then add the pattern fix (or IP allowlist entry) that caused the false positive — otherwise they get re-banned on the next matching request.

Decide your response early. A hard 403 is fine for scanners. For anything that might catch real users, prefer a 404 or redirect to a static page — bans that leak "you are blocked" information invite probing.

Layer it under your existing WAF, not instead of it. This is a cheap first-pass filter for application-level noise; it does not replace rate limiting (use Laravel's throttle) or a real WAF.

Testing. Disable the guard in the testing environment via config, or your feature tests will trip it when they hit non-existent routes to assert 404s. Add an explicit test that a known scanner path returns your configured block response.

Gotchas and Tips

  • Banning 404s is dangerous. If your config matches "too many 404s" and your app legitimately 404s on deleted content or missing favicons, you will ban real users. Prefer path-pattern matching over 404-count heuristics.
  • Health checks and asset requests. /up, /health, /favicon.ico, and robots.txt should be allowlisted or excluded from pattern matching — many scanners probe these, and so does your own infrastructure.
  • Self-lockout. You can ban your own admin IP with a mistyped pattern. Keep an allowlist entry for your IP, and know the console command (or direct DB delete) to lift a ban before you need it.
  • Config caching. Config values are cached; env vars inside a cached config are null at runtime. After editing, always config:clear.
  • Migration ordering. The tables are published into your app. If you deploy with migrate --force in CI, make sure the publish step runs before migrate.
  • IP bans and sessions. A ban blocks new requests but does not invalidate an already-authenticated session held elsewhere. For real abuse, also revoke sessions/tokens.
  • Performance. Every request passes through the guard. Keep the pattern list short, avoid a database query on the hot path (cache the ban list), and prefer denying from cache with a DB write only on the first hit.
  • Chart history is now stable across purge/unban (1.2.0). If you previously set retention to "forever" to keep the widget populated, you can lower it. Existing pre-1.2.0 purge damage cannot be backfilled — the series starts from the upgrade. If your dashboard looked suspiciously empty after an unban, this is why.
  • Dependency bumps in 1.2.0 are dev/CI only. The testbench ^10.0 || ^11.0 widening and the actions-deps updates do not change your installed runtime packages — do not read them as a Laravel 12 support guarantee for the package itself; check the illuminate/* / filament/* constraints in composer.json before upgrading a major Laravel version.
  • Extension points. The ban model, the detection/pattern matching, and the block response are the three places people usually subclass or override. Publish the views if you want to change the widget or the blocked-user page rather than editing vendor code.
  • Debugging a suspected false ban: search the ban record for the matched pattern and the recorded user agent, then replay the request with curl against a staging allowlist to confirm the rule is what you think it is.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource