From a3cd9f4d039b64bebf1319d2b3e5e73b3306bb11 Mon Sep 17 00:00:00 2001 From: chenxi Date: Wed, 16 Sep 2026 11:16:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Livewire=20=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=AF=BC=E8=87=B4=E6=9C=AC=E6=9C=BA=E7=BD=91=E5=9D=80?= =?UTF-8?q?=E8=A2=AB=E9=98=B2=E7=81=AB=E5=A2=99=E5=B0=81=E7=A6=81=20(#194)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/firewall.php | 5 ++- .../Firewall/LivewireXssExclusionTest.php | 43 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/Firewall/LivewireXssExclusionTest.php 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' => ''], + )); + } +}