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

Livewire Injection Stopper Laravel Package

darvis/livewire-injection-stopper

Protect your Laravel + Livewire app from spam bots and injection attacks. This package blocks automated bots, audits Livewire components for manipulable public properties, and silences bot-triggered exceptions so your Sentry logs stay clean.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require darvis/livewire-injection-stopper
    

    The middleware registers itself into the web group — you do not assign it to individual routes.

  2. Read three pages, in this order (new in v1.3.1):

    • Installation — includes a "Check that it works" section. Do this before anything else; it's the fastest way to confirm the middleware is actually in the stack.
    • Quick start — the 5-minute path from install to a blocked request.
    • Troubleshooting — organised as symptom → cause → fix, and it quotes the literal log messages the package emits. When something doesn't block, grep this page for the exact log line you're seeing rather than guessing.
  3. First use case — confirm a block, then audit:

    php artisan livewire:audit
    

    Then follow the Testing page to reproduce a blocked update request. Expect output ending in a Total: line plus a 📖 See https://livewire.laravel.com/docs/locked … link.

  4. Where to look first:

    • Config file — the only real tuning surface (block_all_array_injections, scalar_properties, whitelist_routes).
    • Audit output — your first action list for #[Locked] gaps.
    • Docs home page — v1.3.1 adds a docs guard test that verifies every page is linked and every relative link/anchor resolves, so the home page is now a genuinely reliable index.

Implementation Patterns

Core Workflows

  1. Blocking top-level array injection (the main event): The middleware inspects Livewire update requests and rejects top-level array keys used to smuggle state (e.g. activeFilters[tags]=...). It sits at the end of the web group, so:

    • CSRF is validated before the package sees the request (see Gotchas).
    • Requests without a User-Agent are never blocked by the default rules.
  2. Route whitelisting:

    // config/livewire-injection-stopper.php
    'whitelist_routes' => [
        'admin/*',          // '*' also matches slashes — 'admin/*' covers admin/users/1/edit
        'webhooks/stripe',
    ],
    

    Note that * matches across /, so a pattern like admin/* is broader than it looks.

  3. Tightening scalar_properties:

    'scalar_properties' => [
        'email',       // must be lowercase
        'firstname',   // NOT 'firstName' — see Gotchas
        'form.email',  // whole-name match; 'email' does not cover 'form.email'
    ],
    

    Entries are compared against the whole property name after lowercasing the name. The entries themselves are not lowercased for you.

  4. Audit in CI/CD:

    # .github/workflows/security.yml
    - run: composer install
    - run: php artisan livewire:audit
    

    Pair it with a scheduled run so drift from newly added public properties gets caught:

    $schedule->command('livewire:audit')->weekly();
    

    Treat a non-empty Total: as a failure signal; do not treat ✅ No security issues found! as proof (see Gotchas).

  5. Error handling — let the package do it: Since 1.3.0 the package hooks Livewire's dontReport() and reportable() only. You don't register a custom exception handler class; the block response comes from the middleware. If you want visibility, add a dedicated log channel and check it during incident triage:

    'channels' => [
        'injection_attempts' => [
            'driver' => 'single',
            'path' => storage_path('logs/injection_attempts.log'),
            'level' => 'warning',
        ],
    ],
    

Integration Tips

  • Prefer #[Locked] on any property a client must not set. The audit exists to find the ones you forgot; the attribute is the fix.
  • Use the Testing page's complete feature test as a template — it's the only documented way to prove that an array-injection request is actually blocked end-to-end.
  • Read the Troubleshooting page before opening an issue. The symptom/cause/fix table maps directly onto the log messages the package writes, which is faster than instrumenting the middleware yourself.
  • Keep components inside app/Livewire if you want them audited (see the scan limits in Gotchas).

Implementation Patterns — nothing else changes in the runtime; v1.3.1 is documentation-only.

Gotchas and Tips

Pitfalls

  1. scalar_properties entries must be lowercase. The property name is strtolower'd before comparison, but your config entries are not. firstName will never match $firstName. Write firstname.

  2. scalar_properties matches the whole name. 'email' does not cover form.email. List every fully-qualified name you need.

  3. Nested/dotted names are only partly exempt. A name containing a dot skips the block_all_array_injections rule — but it is still blocked when the whole name starts with one of the fixed prefixes, e.g. activeFilters.tags, hidden.0. Don't assume dotted means safe.

  4. A published config list replaces the defaults entirely. Publishing and editing whitelist_routes (or any list) drops the package's defaults rather than merging. Copy the defaults across before you edit.

  5. CSRF fires first. Because the middleware is at the end of the web group, a POST without a valid token gets Laravel's 419 before the package ever runs. A 419 is not evidence that blocking works.

  6. No User-Agent = never blocked. Requests without a UA bypass the bot rules. If you're testing with curl, remember -A.

  7. The audit silently skips a lot. It does not report:

    • components whose file lacks extends Component (e.g. your own intermediate base class),
    • properties without a default value,
    • types float, array, ?string, ?int, and any namespaced class type,
    • the combined attribute #[Locked, Url],
    • a single-line #[Locked] public bool $x = false; — that line is not recognised at all, so the property is simply invisible to the scan (not a false positive, a false negative).

    This is now documented on the Security audit page as an explicit list of limits — read it before trusting a clean run.

  8. ✅ No security issues found! is not proof. The same message is printed when app/Livewire doesn't exist. Always check the directory exists and the Total: line makes sense for your component count.

  9. Livewire::test() does not exercise the middleware. Component tests do go through the HTTP layer, but with all middleware disabled (including CSRF token verification — don't send one). That means a green component test does not demonstrate that a top-level array update is blocked in a real browser. Use the feature test on the Testing page for that claim.

  10. Debug mode changes Livewire 4's behaviour. "Livewire rejects wrong-type values with a 419" is true only outside debug mode. In debug mode it rethrows the TypeError. Don't write an assertion that holds in one mode only.

  11. The block response is text/html, Laravel's default Content-Type: text/html; charset=utf-8 — not plain text. Assert accordingly.

Debugging

  • Exact log strings beat intuition. The Troubleshooting page lists the literal messages; match your storage/logs/laravel.log against them.
  • Confirm the middleware is in the group by following the Installation page's "Check that it works" step rather than dumping $middleware (it's appended to web, not to the global stack, so it's easy to miss).
  • Audit misses a real property? Check the skip list above first: default value present? type not in the excluded set? file contains extends Component? After adding components, composer dump-autoload.
  • Nothing is blocking? Verify a User-Agent is present, the route isn't matched by a * whitelist pattern, and the name doesn't start with one of the fixed prefixes.

Extension Points

  • Config over code. whitelist_routes, scalar_properties and block_all_array_injections cover most day-to-day needs without subclassing anything.
  • Fixed prefixes are the lever for blocking dotted names — that's where the package's prefix handling lives, and it's the only rule that still applies once a dot is present.
  • Livewire's own #[Locked] is the primary hardening tool; the audit and the block are complementary. The audit finds missing locks; the middleware stops the injection attempts that get past them.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings