fix: UUID-Hashes (Datenschutz-Link) nicht als truncated-ID blocken

Der Integer-Truncation-Filter aus Runde 12 war zu breit: er hat jedes
Pfad-Segment geblockt, das mit einer Ziffer beginnt und nicht aus
reinen Ziffern besteht – also auch UUIDs wie
"3018c9b9-b337-4c9a-a402-b47872f8ddae". Damit warf der Datenschutz-
Link beim ersten Aufruf "Ungültiger Link" (in Wahrheit 400 vom Filter).

Engere Heuristik: ^\d+[a-zA-Z]+$ – reine Ziffern gefolgt von reinen
Buchstaben (`6abc`, `12foo`). UUIDs haben Bindestriche und Hex-
Buchstaben gemischt, werden korrekt durchgelassen.

Live-verifiziert: Datenschutz-Link mit UUID → 200; /customers/6abc →
weiterhin 400; /customers/3 → 200.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-17 09:21:52 +02:00
parent 28c91759df
commit 3dea381983
+7 -4
View File
@@ -268,12 +268,15 @@ app.use('/api', (_req, res, next) => {
// Validierung. Pentest Runde 7 (2026-05-17), LOW.
//
// `app.param()` greift nicht auf in Sub-Router gemounteten Routes, deshalb
// machen wir es als Pfad-Heuristik: jedes Segment, das mit einer Ziffer
// beginnt aber nicht aus reinen Ziffern besteht (`6abc`, `12foo`), wird als
// Tippfehler/Manipulation behandelt.
// machen wir es als Pfad-Heuristik. Geblockt wird NUR `^\d+[a-zA-Z]+$`
// reine Ziffern gefolgt von reinen Buchstaben (`6abc`, `12foo`). UUIDs wie
// `3018c9b9-b337-4c9a-a402-b47872f8ddae` (Consent-Hash) und Datumsstrings
// `2024-05-17` haben Bindestriche / gemischten Aufbau und werden korrekt
// nicht geblockt.
const TRUNCATED_ID_PATTERN = /^\d+[a-zA-Z]+$/;
app.use('/api', (req, res, next) => {
for (const seg of req.path.split('/')) {
if (seg.length > 0 && /^\d/.test(seg) && !/^\d+$/.test(seg)) {
if (seg.length > 0 && TRUNCATED_ID_PATTERN.test(seg)) {
res.status(400).json({ success: false, error: 'Ungültige ID im URL-Pfad' });
return;
}