From 64898195a30003873dd554d60f0f96d594653ff1 Mon Sep 17 00:00:00 2001 From: fds2610-bot Date: Mon, 27 Jul 2026 12:07:29 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20#132:=20Reflektiertes=20XSS=20=C3=BCber?= =?UTF-8?q?=20=5Ferror-Parameter=20behoben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Changes.md | 7 ++ src/Controllers/InvoiceController.php | 2 +- src/Views/belege/detail.php | 2 +- src/Views/invoices/book.php | 2 +- tests/65_InvoiceBookReflectedXssTest.php | 84 ++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 tests/65_InvoiceBookReflectedXssTest.php diff --git a/Changes.md b/Changes.md index 6a645c7..d042516 100644 --- a/Changes.md +++ b/Changes.md @@ -2,6 +2,13 @@ --- +## 2026-07-27 – Fix: Reflektiertes XSS über _error-Parameter bei Rechnungs-Zahlungserfassung (Issue #132) + +- `InvoiceController::book()` übernahm den Fehler-Array ungeprüft direkt aus `$_GET['_error']` und reichte ihn an die View weiter. Da `_error` nirgendwo serverseitig befüllt wird und der CSRF-Schutz nur für POST/PUT/DELETE/PATCH greift, konnte ein Angreifer per einfachem Link (`GET /invoices/{id}/book?_error[x]='; + $getBackup = $_GET; + $_GET['_error'] = ['x' => $payload]; + + try { + $controller = new \Steuerkram\Controllers\InvoiceController(); + ob_start(); + $controller->book(['id' => (string)$invoiceId]); + $html = ob_get_clean(); + } finally { + $_GET = $getBackup; + } + + $this->assert( + !str_contains($html, $payload), + 'Roher