R145-Hygiene: limit-Floor + getContracts fail-closed (Konsistenz)

Pentester R145 (nice-to-have, keine Findings):
1) listAll: limit bekommt einen Floor (Math.max(1, ...)) - limit=-5
   ergab vorher take:-5 an Prisma. page ebenso auf >=1 geklemmt.
2) getContracts nutzte dasselbe 'if (isCustomerPortal && customerId)'-
   Muster und war NICHT fail-closed. Jetzt konsistent zu listAll:
   - Controller: Portal-Token immer gescoped (ohne customerId -> []).
   - Service getAllContracts: 'if (customerIds)' statt '.length > 0',
     damit ein leeres Array strikt auf IN () filtert (0 Treffer) statt
     durchzufallen. Einziger Caller ist der Contract-Controller ->
     keine Regression fuer den Normalfall.

Verifiziert: Staff -> alle; Portal customerIds=[] -> 0 Vertraege/Belege.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 11:32:21 +02:00
co-authored by Claude Opus 4.8
parent 4c5548ea3c
commit 8d93c1767b
3 changed files with 20 additions and 14 deletions
+13 -10
View File
@@ -96,17 +96,20 @@ export async function getContracts(req: AuthRequest, res: Response): Promise<voi
return;
}
// Für Kundenportal-Benutzer: nur eigene + vertretene Kunden MIT Vollmacht
// Für Kundenportal-Benutzer: nur eigene + vertretene Kunden MIT Vollmacht.
// Fail-closed (Pentest R145): Portal-Token wird IMMER gescoped; fehlt wider
// Erwarten die customerId, ergibt das eine leere Menge (nicht alle).
let customerIds: number[] | undefined;
if (req.user?.isCustomerPortal && req.user.customerId) {
// Eigene Customer-ID immer
customerIds = [req.user.customerId];
// Vertretene Kunden nur wenn Vollmacht erteilt
const representedIds: number[] = req.user.representedCustomerIds || [];
for (const repCustId of representedIds) {
const hasAuth = await authorizationService.hasAuthorization(repCustId, req.user.customerId);
if (hasAuth) {
customerIds.push(repCustId);
if (req.user?.isCustomerPortal) {
customerIds = req.user.customerId ? [req.user.customerId] : [];
if (req.user.customerId) {
// Vertretene Kunden nur wenn Vollmacht erteilt
const representedIds: number[] = req.user.representedCustomerIds || [];
for (const repCustId of representedIds) {
const hasAuth = await authorizationService.hasAuthorization(repCustId, req.user.customerId);
if (hasAuth) {
customerIds.push(repCustId);
}
}
}
}