Pentest R93: Leerer String != fehlender Query-Param
R93.1 INFO: ?accountId= (explizit-leer) wurde wie ?accountId weggelassen behandelt → 200 statt 400 auf optionalen Endpunkten. Pentester-Spec: leerer String ist keine gültige Zahl. Fix in parsePositiveIntQuery: nur `v === undefined` ist absent; '', ' ', alles andere muss parsen. Required + optional Modes unverändert. Sanity-Test: alle 11 Cases grün. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -64,8 +64,13 @@ function parsePositiveIntQuery(
|
||||
res: Response,
|
||||
options?: { required?: boolean },
|
||||
): number | undefined | null {
|
||||
const absent = v === undefined || v === '' || (typeof v === 'string' && v.trim() === '');
|
||||
if (absent) {
|
||||
// Pentest 93.1 (INFO, 2026-06-21): `?accountId=` (explizit-leer) wurde
|
||||
// wie `?accountId` weggelassen behandelt → 200 statt 400 auf optionalen
|
||||
// Endpunkten. Spec sagt aber: leerer String ist KEINE gültige Zahl.
|
||||
// Trennung jetzt strikt:
|
||||
// - Param fehlt komplett (`undefined`) → "absent"
|
||||
// - Param da, aber Wert leer/Whitespace/keine Zahl → invalid → 400
|
||||
if (v === undefined) {
|
||||
if (options?.required) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
@@ -82,7 +87,15 @@ function parsePositiveIntQuery(
|
||||
} as ApiResponse);
|
||||
return null;
|
||||
}
|
||||
const n = parseInt(v, 10);
|
||||
const trimmed = v.trim();
|
||||
if (trimmed === '') {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: `${fieldLabel} darf nicht leer sein – bitte weglassen oder positive Ganzzahl angeben.`,
|
||||
} as ApiResponse);
|
||||
return null;
|
||||
}
|
||||
const n = parseInt(trimmed, 10);
|
||||
if (!Number.isFinite(n) || n < 1 || !Number.isInteger(n)) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
|
||||
@@ -97,6 +97,16 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
||||
|
||||
## ✅ Erledigt
|
||||
|
||||
- [x] **🔒 Pentest R93 – Leerer String != fehlender Param**
|
||||
- R93.1 (INFO): `?accountId=` (explizit-leer) wurde wie `?accountId`
|
||||
weggelassen behandelt → 200 statt 400 auf optionalen Endpunkten.
|
||||
Pentester-Spec: leerer String ist KEINE gültige Zahl.
|
||||
- Fix im `parsePositiveIntQuery()`-Helper: striktere Absent-Logik
|
||||
(`v === undefined` ist absent; `''`, `' '`, alles andere muss
|
||||
parsen). Required + optional Modes unverändert.
|
||||
- Float-Grenzfall (`accountId=5.5` → 5 via `parseInt`) bleibt als
|
||||
by-design akzeptiert (Pentester-Bestätigung, kein Security-Impact).
|
||||
|
||||
- [x] **🔒 Pentest R92 – Strict-400 für accountId auf Vertrags-Endpunkten**
|
||||
- R91-Fix war silent-undefined bei invaliden Werten: `accountId=abc`
|
||||
auf `GET /contracts/:id/emails` ergab "kein Filter" → Mailbox-
|
||||
|
||||
Reference in New Issue
Block a user