How to Prevent Cross-Site Scripting (XSS) in Laravel
XSS vulnerabilities allow attackers to inject malicious scripts into your Laravel pages. Learn how to prevent XSS with proper output encoding.
The Problem
Cross-site scripting (XSS) vulnerabilities allow attackers to inject malicious JavaScript into web pages viewed by your users, enabling session hijacking, credential theft, and page defacement. While Laravel's Blade engine escapes output by default with {{ }}, XSS is introduced when developers use unescaped output {!! !!}, render user input in JavaScript contexts, or output data in HTML attributes without proper encoding.
How to Fix
-
1
Always use escaped Blade output
Use {{ }} (double curly braces) for all user-generated content. This automatically HTML-encodes the output:
{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>Only use {!! !!} for content you have explicitly sanitized or that you generated yourself (like rendered Markdown from trusted sources).
-
2
Sanitize HTML when you must allow it
If you need to allow HTML (rich text editors, Markdown), sanitize it before storage and display:
{{ trim($paragraph)); ?>Then sanitize on input:
use Mews\Purifier\Facades\Purifier;
{{ trim($paragraph)); ?>Configure allowed tags in config/purifier.php:
{{ trim($paragraph)); ?>Always sanitize on input (before saving) and still use {!! !!} only with sanitized content.
-
3
Handle JavaScript context safely
Never output user data directly into JavaScript:
{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>The @json directive properly escapes data for JavaScript contexts, preventing injection through string breakout.
-
4
Add Content-Security-Policy header
Add a CSP header to prevent inline script execution, which blocks most XSS attacks even if a vulnerability exists:
{{ trim($paragraph)); ?>With CSP in place, injected scripts cannot execute because the browser blocks inline JavaScript. This provides defense-in-depth alongside proper output encoding.
See the missing-security-headers guide for full middleware implementation.
How to Verify
Test by entering XSS payloads in your forms:
<script>alert('xss')</script> <img src=x onerror=alert('xss')> <svg onload=alert('xss')>
The text should be displayed literally on the page (you see the HTML tags as text) and never execute as JavaScript. Check the page source to verify the output is HTML-encoded.
Prevention
Establish a coding standard that requires code review approval for any use of {!! !!} in Blade templates. Use @json for JavaScript context output. Add Content-Security-Policy headers. Run automated XSS scanning tools like OWASP ZAP against your application regularly.
Frequently Asked Questions
Does Blade's {{ }} protect against all XSS?
Blade {{ }} protects against XSS in HTML context by encoding <, >, &, ", and '. However, it does not protect when outputting into JavaScript, CSS, or URL contexts. Use @json for JavaScript, and always validate/sanitize URLs before outputting them in href attributes.
Is Livewire vulnerable to XSS?
Livewire uses Blade rendering, so the same rules apply. Properties rendered with {{ }} are safe. If you use wire:model on contenteditable elements or render HTML with {!! !!}, you need to sanitize the content. Livewire's Alpine.js directives should also be checked for user input rendering.
What about XSS in Markdown rendering?
Markdown parsers like league/commonmark can be configured to strip HTML. Use the disallowed_raw_html extension or pipe output through HTMLPurifier. Never trust that Markdown alone prevents XSS, as most parsers allow inline HTML by default.
Related Security Terms
Related Guides
How to Fix Missing Security Headers in Laravel
Your Laravel app is missing critical security headers like CSP, HSTS, and X-Frame-Options. Learn how to add them with middleware.
How to Fix Missing CSRF Protection in Laravel
Your Laravel forms are missing CSRF tokens, leaving users vulnerable to cross-site request forgery attacks. Learn how to fix this.
How to Prevent SQL Injection in Laravel
SQL injection vulnerabilities in raw queries and improper Eloquent usage can expose your database. Learn how to write secure queries.
Detect This Automatically with StackShield
StackShield continuously monitors your Laravel application from the outside and alerts you when security issues are found. No installation required.
Start Free Trial