Pentest 60.3 MEDIUM: sanitizePhoneField auf Customer + User-Felder ausweiten
Der Fix aus 51.3 deckte nur Contract-PhoneNumber-Felder ab. CRLF in
`Customer.phone`, `Customer.mobile` und (im selben Code-Pfad)
`User.whatsappNumber`, `User.signalNumber` ging weiter durch –
pickCustomerUpdate / pickUserUpdate macht nur stripHtml, das filtert
keine Control-Chars.
- sanitizePhoneField von contract.service nach utils/sanitize gezogen
und EXPORT, damit alle Stellen denselben Allowlist-Check
(/^[0-9+\-/(). ]{0,40}$/) nutzen. Literales Space, NICHT \s.
- customer.controller updateCustomer + createCustomer: phone + mobile
durch sanitizePhoneField → 400 bei CRLF/Control-Chars.
- user.controller updateUser + createUser: whatsappNumber +
signalNumber analog.
- contract.service nutzt jetzt den importierten Helper (Lokale
Kopie entfernt – Single Source of Truth).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -225,6 +225,27 @@ export function validateContractDocumentType(raw: unknown): string {
|
||||
return canonical;
|
||||
}
|
||||
|
||||
// Pentest 51.3 + 60.3 (MEDIUM, 2026-06-01): Telefon-/Vorwahl-Felder
|
||||
// dürfen NIE CRLF oder andere Control-Chars enthalten – sonst sind sie
|
||||
// ein Header-Injection-Vektor (Mail, HTTP), wenn der Wert mal in einen
|
||||
// Header fließt (PDF/Mail-Templates, CSV-Export). Whitespace bewusst auf
|
||||
// literales Space beschränkt, NICHT `\s` – das matched sonst `\r\n\t`.
|
||||
// Allowed: Ziffern, Plus, Minus, Slash, Klammern, Punkt, Space. Bis 40 Zeichen.
|
||||
//
|
||||
// 51.3 deckte nur Contract-Phone-Felder ab; 60.3: `Customer.phone` /
|
||||
// `Customer.mobile` waren immer noch offen, weil pickCustomerUpdate nur
|
||||
// stripHtml laufen ließ – das filtert keine Control-Chars.
|
||||
const PHONE_FIELD_ALLOWED = /^[0-9+\-/(). ]{0,40}$/;
|
||||
export function sanitizePhoneField(raw: unknown, fieldLabel: string): string | undefined {
|
||||
if (raw == null) return undefined;
|
||||
const trimmed = String(raw).trim();
|
||||
if (trimmed === '') return undefined;
|
||||
if (!PHONE_FIELD_ALLOWED.test(trimmed)) {
|
||||
throw new Error(`${fieldLabel} enthält unzulässige Zeichen (erlaubt sind Ziffern, +, Leerzeichen, -, /, Klammern).`);
|
||||
}
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
const NOTES_DEFAULT_MAX = 2000;
|
||||
export function sanitizeNotes(raw: unknown, maxLength: number = NOTES_DEFAULT_MAX): string | null {
|
||||
if (raw == null) return null;
|
||||
|
||||
Reference in New Issue
Block a user