CVE-2026-54181 Overview
CVE-2026-54181 is a stored cross-site scripting (XSS) vulnerability in backpack/crud, a Laravel package that provides Create, Read, Update, and Delete functions for building custom administration panels. The flaw resides in src/resources/views/crud/columns/color.blade.php, where the escaped and raw rendering branches controlled by $column['escaped'] are inverted. Because $column['escaped'] defaults to true, the $column['text'] value is rendered unescaped by default. An attacker with write access to a color column can execute arbitrary JavaScript in the browser of any user, including administrators, who view the CRUD list. The issue affects versions 6.0.0 through 6.8.13 and 7.0.0 through 7.0.37.
Critical Impact
Stored JavaScript executes in an administrator's session context, granting the attacker access to session-backed application capabilities in the Backpack admin panel.
Affected Products
- Laravel-Backpack CRUD versions 6.0.0 through 6.8.13
- Laravel-Backpack CRUD versions 7.0.0 through 7.0.37
- Applications rendering color columns using the affected Blade template
Discovery Timeline
- 2026-09-14 - CVE-2026-54181 published to NVD
- 2026-09-14 - Last updated in NVD database
Technical Details for CVE-2026-54181
Vulnerability Analysis
The vulnerability is a stored XSS issue [CWE-79] in the color column Blade template. Laravel Blade uses {{ }} for HTML-escaped output and {!! !!} for raw, unescaped output. In the vulnerable template, the branches for these two output modes are swapped. When $column['escaped'] is true (the default), the template calls the raw output syntax, injecting $column['text'] directly into the DOM without encoding.
An attacker who can persist a value into a field bound to a color column can embed markup or scripting content. When an administrator loads the CRUD list view, the payload renders in the title attribute and CSS background-color context of a <span> element, enabling script execution or attribute breakout within the admin session.
Root Cause
The root cause is inverted conditional logic in color.blade.php. The if($column['escaped']) branch invokes {!! $column['text'] !!} (raw output), while the else branch invokes {{ $column['text'] }} (escaped output). This inversion causes the safe default configuration to produce unsafe output.
Attack Vector
Exploitation requires two conditions: an attacker with write access to the stored color value, and a victim with permission to view the CRUD list. User interaction is required because the victim must load the affected list page. The attack crosses a trust boundary from a lower-privileged writer to a higher-privileged administrator viewer, matching the scope-change characteristic of stored XSS in admin panels.
// Patch from src/resources/views/crud/columns/color.blade.php
// Source: https://github.com/Laravel-Backpack/CRUD/commit/608652b1020ba274781f222d2959d7780a559a08
@includeWhen(!empty($column['wrapper']), 'crud::columns.inc.wrapper_start')
@if(!empty($column['value']))
@if($column['escaped'])
- <span title="{!! $column['text'] !!}" class="btn rounded-circle" style="font-size: 0.5rem; background-color: {!! $column['text'] !!}"> </span>
+ <span title="{{ $column['text'] }}" class="btn rounded-circle" style="font-size: 0.5rem; background-color: {{ $column['text'] }}"> </span>
@if($column['showColorHex'])
- {!! $column['text'] !!}
+ {{ $column['text'] }}
@endif
@else
- <span title="{{ $column['text'] }}" class="btn rounded-circle" style="font-size: 0.5rem; background-color: {{ $column['text'] }}"> </span>
+ <span title="{!! $column['text'] !!}" class="btn rounded-circle" style="font-size: 0.5rem; background-color: {!! $column['text'] !!}"> </span>
@if($column['showColorHex'])
- {{ $column['text'] }}
+ {!! $column['text'] !!}
@endif
@endif
@else
The patch restores the intended semantics: escaped output when $column['escaped'] is true, raw output when explicitly disabled.
Detection Methods for CVE-2026-54181
Indicators of Compromise
- Stored values in color column fields containing angle brackets, quote characters, or JavaScript syntax such as <script>, onerror=, or javascript:.
- Unexpected outbound requests originating from administrator browser sessions when viewing CRUD list pages.
- Admin account activity from unusual IP addresses following a list view render.
Detection Strategies
- Audit database columns bound to Backpack color fields for non-hex values that deviate from the expected #RRGGBB format.
- Review Content Security Policy (CSP) violation reports for the admin panel, focusing on inline-script or attribute-based violations.
- Inspect web server access logs for POST or PUT requests to Backpack CRUD endpoints containing script-related payloads in color field parameters.
Monitoring Recommendations
- Enable and monitor Laravel application logs for anomalous input rejections on color-typed fields.
- Track administrative session activity for behavior inconsistent with the authenticated user, such as unexpected privilege changes or record deletions.
- Alert on any modification to color.blade.php outside of a controlled deployment pipeline.
How to Mitigate CVE-2026-54181
Immediate Actions Required
- Upgrade backpack/crud to version 6.8.14 or 7.0.38 immediately using Composer.
- Sanitize existing stored values in color columns to strip non-hex content before rendering.
- Rotate administrator session tokens if unsanitized color values are found in the database.
Patch Information
The fix is available in Laravel-Backpack CRUD releases 6.8.14 and 7.0.38. The corrective commit is 608652b, documented in Pull Request #5992. Additional hardening is included in Pull Request #5994. Full context is provided in the GitHub Security Advisory GHSA-mmg4-322v-6jvc.
Workarounds
- Apply input validation on all fields backing color columns to accept only strict hex color patterns such as /^#[0-9a-fA-F]{6}$/.
- Restrict write access to models containing color columns to trusted administrators until the patch is deployed.
- Override the affected color.blade.php view in the application's resources/views/vendor/backpack directory to use escaped {{ }} output for $column['text'].
# Upgrade to a patched release
composer require backpack/crud:^7.0.38
# or for the 6.x branch
composer require backpack/crud:^6.8.14
# Verify installed version
composer show backpack/crud | grep versions
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

