jeffersongoncalves/laravel-scanner-guard
Laravel Scanner Guard detects and blocks vulnerability scanners probing your app for exposed files, admin panels, and known exploit paths. It logs suspicious requests and lets you deny abusive IPs with middleware, helping cut noise and harden your Laravel site with minimal configuration.
The 1.3.0 release materially broadens the package from a database-backed Laravel scanner guard into a deployable edge-protection component with three persistence models: database, cache, and http. Architecturally, this improves fit for Laravel services that cannot assume SQL availability, including stateless containers, read-only filesystems, multi-region satellites, and small services where migrations are undesirable. The http driver introduces a hub-and-spoke model: satellites keep local cache bans and asynchronously forward bans to a central Laravel app over HMAC-signed requests. That is a sound pattern for centralized visibility and nginx export, but it adds a new distributed-system boundary: timestamp freshness, replay protection, secret management, and failure handling now matter operationally.
Integration feasibility is high for the default database driver because behavior is unchanged and no migration action is required. Teams using the package with published config must add the new driver and http keys, but that is configuration drift rather than a forced migration. The main technical risk is the API change: ScannerGuard::ban() now returns ?ScannerGuardBan, returning null for cache and http drivers. Any calling code that assumes a ban object, accesses properties immediately, or type-hints a non-null return will need review. This is a minor-version release but has a behavioral contract change for non-default drivers and potentially for consumers that treat the return value as guaranteed.
The cache driver is operationally simple but intentionally limited: no audit trail, no stats, no nginx export, and bans expire with ban_duration. The http driver is more capable but depends on a central app configured with SCANNER_GUARD_HTTP_SERVER_ENABLED=true; forwarding happens after the response with a short timeout, and failures are only logged. That means the local ban remains authoritative at the satellite, while central visibility is best-effort. This is acceptable for enforcement but not for compliance-grade audit unless supplemented. The central app records its own salted ip_hash, daily stats, and raw IP only in cache, preserving privacy posture, but teams must validate whether hash consistency across satellites matters for their reporting.
Key questions: Which services truly need audit/export versus cache-only enforcement? Is the central app sized and monitored as a dependency for ban visibility, even if not for enforcement? How are HMAC secrets rotated across satellites and the central app? What is the acceptable loss window for forwarded bans? Do any consumers depend on ban() returning a non-null model? Are aggregate-and-prune and export-denylist expected to run anywhere outside database deployments, and are operators aware they now skip with a notice?
Stack fit is strong for Laravel applications already using cache stores and HTTP clients. The cache driver fits ephemeral or low-ops environments where the package only needs to enforce temporary bans locally. The http driver fits a multi-service estate with one central Laravel app responsible for aggregation and nginx denylist export. The database driver remains the best fit where local audit, daily stats, and scheduled export commands are required. This release effectively lets teams choose enforcement-only, centralized-visibility, or full local-audit modes without changing the package.
Migration path should be staged. First, inventory all ScannerGuard::ban() call sites and any code that reads the returned ban model. Add null-safety or branch by driver before changing configuration. Second, for existing database deployments, upgrade with no driver change and verify migrations, scheduled commands, and export output remain unchanged. Third, for teams wanting to remove SQL, publish config and add the driver plus http keys, then switch one non-critical service to cache to validate enforcement and expiration behavior. Fourth, stand up the central app endpoint with SCANNER_GUARD_HTTP_SERVER_ENABLED=true, configure HMAC secrets, and test signature rejection, stale timestamp rejection, and replay handling before onboarding satellites.
Compatibility considerations: the package remains Laravel/PHP-oriented and depends on the host app’s cache and HTTP client configuration. The http driver requires outbound network access from satellites and inbound access to the central endpoint, plus clock synchronization for timestamp validation. The central app must be reachable enough for forwarding, but the short timeout and log-only failure mode mean satellite request latency should not be affected materially. The cache and http drivers do not need migrations, but operators must ensure cache stores are shared or persistent enough for the intended ban lifetime; a per-container array cache would undermine enforcement.
Sequencing recommendation: upgrade package, patch null-return handling, keep database in production, validate cache in a staging or low-risk service, then validate http forwarding with a canary satellite. Only after confirming central ingestion, replay rejection, and nginx export coverage should teams retire SQL from satellites. Keep scheduled command monitoring in place for any remaining database driver deployments, and explicitly remove or silence expectations for aggregate-and-prune and export-denylist on non-database deployments.
Maintenance impact is moderate. Default database deployments see no required action, but published configs need new keys and application code should be checked for null-return assumptions. The cache driver reduces maintenance by eliminating migrations and SQL, but also removes audit and export capabilities, so teams must accept reduced observability. The http driver adds central-app maintenance: endpoint availability, HMAC secret management, timestamp/replay validation, and monitoring of forwarded-ban ingestion. Because forwarding is after the response and failures are only logged, operational dashboards should track log-based failure rates rather than relying on user-facing errors.
Support impact shifts toward configuration and networking questions. Support teams will need clear guidance on driver selection, expected ban() return values, and why audit/export commands skip outside database. The HMAC signature format and timestamp freshness window should be documented with troubleshooting steps for 403 and 409 responses. Central app operators need runbooks for secret rotation, stale clock issues, replay false positives, and cache eviction of raw IPs.
Scaling impact is favorable for satellites using cache or http: no SQL writes on the hot path and no migration overhead. The central app becomes the scaling bottleneck for aggregated stats and nginx export, but because forwarding is best-effort and after-response, satellite request handling should remain stable under central degradation. The local cache remains the enforcement source for cache/http, so ban duration and cache capacity must be sized for expected ban volume. The central app’s cache must also be sized for raw IP retention and replay protection.
Failure modes: if the central app is down, satellites still enforce local bans but central visibility and nginx export lag or lose events. If HMAC secrets drift, all forwarded bans are rejected with 403 and only logged. If clocks skew beyond the stale-timestamp threshold, valid bans are rejected. If replay detection is too aggressive or cache-backed replay state is evicted, duplicates may be accepted or rejected unexpectedly. If ban() callers assume a model, they may throw or mis-handle null under cache/http. If operators expect aggregate-and-prune or export-denylist to run under non-database drivers, those commands will skip with only a notice, creating silent gaps unless monitored.
Ramp-up is low for teams already familiar with Laravel config, cache, and HTTP client patterns. The main learning curve is the distributed model: deciding which driver each service uses, understanding that cache/http have no local audit trail, and operating the central receiver. A short enablement note covering driver selection, null-return handling, HMAC setup, and command behavior outside database should be sufficient for most Laravel teams.
How can I help you explore Laravel packages today?