Security-Hardening Runde 3: JWT, trust-proxy, weitere IDORs, Attachment-Härtung
- JWT-Algorithmus fest auf HS256 (Defense-in-Depth gegen alg-confusion)
- app.set('trust proxy', 1) – Rate-Limiter wirkt jetzt auch hinter Reverse-Proxy
- IDOR-Fix: Invoice-ECD-Endpoints + PDF-Template-Generierung (canAccessContract/ECD)
- Email-Anhang-Download: Content-Type-Safelist, SVG nie inline, nosniff, Filename-CRLF-Sanitize
- Provider/Tariff-GET-Routen: requirePermission('providers:read') (Portal-Kunden raus)
- SMTP-Header-Injection zentral in sendEmail blockiert (schützt alle Caller)
- bcrypt-Cost 10 → 12 (OWASP 2026)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -224,3 +224,24 @@ export async function canAccessCachedEmail(
|
||||
'E-Mail',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zugriff auf ein EnergyContractDetails prüfen (ECD → Contract → customerId).
|
||||
*/
|
||||
export async function canAccessEnergyContractDetails(
|
||||
req: AuthRequest,
|
||||
res: Response,
|
||||
ecdId: number,
|
||||
): Promise<boolean> {
|
||||
if (!req.user?.isCustomerPortal) return true;
|
||||
const ecd = await prisma.energyContractDetails.findUnique({
|
||||
where: { id: ecdId },
|
||||
select: { contract: { select: { customerId: true } } },
|
||||
});
|
||||
return canAccessResourceByCustomerId(
|
||||
req,
|
||||
res,
|
||||
ecd?.contract?.customerId,
|
||||
'Energievertrag',
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user