diff --git a/config/firewall.php b/config/firewall.php
index d3675728..cdcac1dc 100644
--- a/config/firewall.php
+++ b/config/firewall.php
@@ -418,7 +418,10 @@ return [
'inputs' => [
'only' => [], // i.e. 'first_name'
- 'except' => [], // i.e. 'password'
+ // Livewire cryptographically signs this serialized component
+ // state. Its large JSON payload produces false positives; user
+ // updates and every other request field remain protected.
+ 'except' => ['snapshot'],
],
'patterns' => [
diff --git a/tests/Unit/Firewall/LivewireXssExclusionTest.php b/tests/Unit/Firewall/LivewireXssExclusionTest.php
new file mode 100644
index 00000000..eb44af06
--- /dev/null
+++ b/tests/Unit/Firewall/LivewireXssExclusionTest.php
@@ -0,0 +1,43 @@
+ true]);
+ }
+
+ public function test_signed_livewire_snapshot_is_excluded_from_xss_scanning(): void
+ {
+ $middleware = new Xss();
+ $middleware->prepare(Request::create('/1/livewire/update', 'POST'));
+
+ $this->assertFalse($middleware->match(
+ $middleware->getPatterns()[4],
+ ['components' => [['snapshot' => '{"data":{"product_name":"
"}}']]],
+ ));
+ }
+
+ public function test_livewire_user_updates_and_regular_fields_remain_protected(): void
+ {
+ $middleware = new Xss();
+ $middleware->prepare(Request::create('/1/livewire/update', 'POST'));
+
+ $this->assertSame(1, $middleware->match(
+ $middleware->getPatterns()[4],
+ ['components' => [['updates' => ['name' => '
']]]],
+ ));
+ $this->assertSame(1, $middleware->match(
+ $middleware->getPatterns()[4],
+ ['name' => '
'],
+ ));
+ }
+}