Pentest 69.3 (INFO): Magic-Byte-Validator auf Vertragsdokumente erweitert

contract.routes.ts Vertragsdokumente-Upload hatte bisher nur den
PDF-Inhalts-Scan aus 68.1. JPG/PNG-Uploads waren ungeprüft, ohne
canonical Rename – Pentester selbst attestiert "ohne Exploit-Pfad"
(Download-Layer fängt's), aber inkonsistent zu allen anderen
Upload-Pfaden.

- Refactor: detectType + validateUploadedFile aus upload.routes.ts
  in neue Middleware uploadFileTypeValidator.ts ausgelagert (Single
  Source of Truth, ~90 Zeilen Duplikation entfällt).
- contract.routes.ts: validateUploadedFile ersetzt
  scanUploadedPdfIfPresent → Magic-Byte + canonical Rename + PDF-Scan
  in einer Pipeline.
- pdfUploadSafety.ts: scanUploadedPdfIfPresent entfernt (tot).
This commit is contained in:
2026-06-03 14:49:06 +02:00
parent ec577e6d76
commit 9cfd2e4a64
5 changed files with 130 additions and 130 deletions
+6 -34
View File
@@ -3,42 +3,14 @@ import fs from 'fs';
import { assertSafePdf } from '../utils/sanitize.js';
import { ApiError } from '../utils/apiError.js';
/**
* Express-Middleware nach multer.single(...): wenn die abgelegte Datei
* eine PDF ist (Magic-Byte %PDF-), wird sie auf gefährliche aktive
* Inhalte (JS / Launch / EmbeddedFile / RichMedia) gescannt. Bei
* Verstoß: Datei vom Disk löschen + JSON-Error zurückgeben. Non-PDF-
* Dateien passieren ohne Validierung diese Middleware ist NICHT der
* Magic-Byte-Check für andere Typen.
*
* Pentest 68.1 (LOW, 2026-06-03): Routen, die PDFs annehmen
* (gdpr.routes Vollmacht, contract.routes Vertragsdokumente,
* pdfTemplate.routes) haben bisher nur den client-gemeldeten mimetype
* geprüft; gefährliche PDFs kamen durch.
*/
export function scanUploadedPdfIfPresent(req: Request, res: Response, next: NextFunction): void {
const file = (req as Request & { file?: Express.Multer.File }).file;
if (!file) {
next();
return;
}
try {
const buf = fs.readFileSync(file.path);
if (buf.length >= 5 && buf.subarray(0, 5).toString('latin1') === '%PDF-') {
assertSafePdf(buf);
}
next();
} catch (e) {
try { fs.unlinkSync(file.path); } catch { /* ignore */ }
const status = e instanceof ApiError ? e.statusCode : 415;
const message = e instanceof Error ? e.message : 'PDF ungültig';
res.status(status).json({ success: false, error: message });
}
}
/**
* Strikte Variante: Datei MUSS eine PDF sein. Sonst 415. Für Routen, die
* ausschliesslich PDFs zulassen (z.B. Vollmacht-Upload).
* ausschliesslich PDFs zulassen (z.B. Vollmacht-Upload, PDF-Templates).
*
* Routen, die auch JPG/PNG akzeptieren (z.B. contract.routes
* Vertragsdokumente), nutzen `validateUploadedFile` aus
* `uploadFileTypeValidator.ts` das macht Magic-Byte für ALLE Typen +
* PDF-Scan in einer Pipeline.
*/
export function requireSafeUploadedPdf(req: Request, res: Response, next: NextFunction): void {
const file = (req as Request & { file?: Express.Multer.File }).file;