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

Xss Middleware Laravel Package

alkhwlani/xss-middleware

Laravel middleware that sanitizes incoming request data to help prevent XSS attacks. It filters user input and removes malicious HTML/scripts, adding a simple protection layer to your app without changing your existing validation flow.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package:
    composer require alkhwlani/xss-middleware
    
  2. Publish its config so you can inspect the strip/allow rules:
    php artisan vendor:publish --provider="Alkhwlani\XssMiddleware\...ServiceProvider"
    
    If no publish tag is documented, check the package's config/ directory in vendor/alkhwlani/xss-middleware first — that's where the tag lists, allowed HTML, and iframe/embed rules live.
  3. Register the middleware. On Laravel 11+ add it in bootstrap/app.php:
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->append(\Alkhwlani\XssMiddleware\...::class); // global
        // or $middleware->web(append: [...]) for web-only
    })
    
    On Laravel 10 and below, add it to the $middleware (global) or $middlewareGroups['web'] array in app/Http/Kernel.php.
  4. First use case: drop it on the web group and submit a comment/bio containing <script>alert(1)</script> or <iframe src="...">. Inspect $request->all() in a controller — it should arrive stripped. That's the entire value proposition: every controller downstream gets cleaned input without per-form code.

Implementation Patterns

  • Scope it to the web group, not global. API endpoints usually receive JSON and may be better served by dedicated request sanitization; running an HTML stripper over every JSON body is noise. If you do need APIs covered, verify it reads $request->json() and not only $request->request.
  • Sanitize, then validate. Register this middleware before your FormRequest validation runs (it is if appended to the group), so validators see cleaned values. If you validate first and sanitize after, required|string checks can pass on payloads that later get mangled.
  • Keep output escaping as the real defense. This package is an input filter. Blade's {{ }} and e() are still your primary XSS control; treat this as defense-in-depth for stored content, especially if you ever render with {!! !!}.
  • Rich text needs a whitelist, not a blacklist. If your app allows authors to submit <p>, <b>, <a> via a WYSIWYG, configure the allowed-tag list in the package config or the middleware will strip legitimate markup. Do not attempt to "allow iframes" for embed widgets — sanitize them into a placeholder and re-render with a trusted oEmbed service client-side.
  • Wire it into a pipeline for admin/moderated content. A common pattern: middleware strips everything by default; a privileged, server-side sanitizer (e.g. HTMLPurifier) runs only when a moderator explicitly approves raw HTML. Keep the two paths separate.
  • Add regression tests. In a feature test, POST payloads like <img src=x onerror=alert(1)>, javascript: hrefs, and nested <iframe>s, then assert the stored/returned value contains no onerror/javascript:/<iframe. This locks behavior if the package updates.
  • Central integration point: if you have a SanitizesInput trait or a base FormRequest, call the package's sanitizer there as a fallback so behavior is identical whether traffic went through middleware or a queued job/console command.

Gotchas and Tips

  • Middleware is bypassed by anything not going through HTTP. Console commands, queued jobs, imports, and seeders all write directly to the DB. If sanitization only lives in middleware, those paths are unprotected. Sanitize again at the model/mutator or service layer if data can enter from multiple sources.
  • JSON and array payloads. Confirm the package recurses into nested arrays and application/json bodies. A single-level array_map with strip_tags will miss payload[0][field]. Test with Postman/curl -H "Content-Type: application/json".
  • Double-encoding and HTML entities. Payloads like &lt;script&gt; or %3Cscript%3E are decoded by browsers/servers at different stages. Verify the middleware decodes entities before stripping, or you will pass through a payload that a downstream html_entity_decode (or a careless template) turns back into executable script.
  • Config drift after updates. Publish the config and commit it. A composer update that adds new default strip rules (or new allowed tags) can silently change what user content looks like after deploy. Diff the vendor config against yours on upgrade.
  • Performance on large bodies. HTML-stripping regex passes over multi-megabyte request bodies (bulk imports, markdown editors) add latency. Consider route-level application so heavy upload endpoints in the web group aren't penalized — or set the middleware to skip when Content-Length exceeds a threshold.
  • Do not rely on it for SQL injection or CSRF. It filters markup, not query syntax. Keep parameterized queries/Eloquent bindings and existing CSRF middleware exactly as they are.
  • Debugging a "disappearing content" bug: temporarily move the middleware off the global stack and run it manually in a tinker session (app(YourMiddleware::class)->handle($request, fn($r) => $r)) to see precisely which tags/attributes get removed. Keep a Log::debug of the before/after diff in local development.
  • Extension point: if the config list is insufficient, wrap the package middleware in your own SanitizeInput middleware that calls the parent and then applies app-specific rules (e.g., strip style attributes, normalize URLs). This keeps you upgrade-safe rather than editing vendor code.
  • Small-package risk. With ~5 stars and no dependents, expect sparse docs and slow issue responses. Pin the version in composer.json ("alkhwlani/xss-middleware": "^1.0") and cover it with your own tests; the maintenance burden is effectively yours.
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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk