- Ghostscript läuft auf PDFs aus Mails und vom Scanner jetzt mit -dSAFER
statt -dNOSAFER (kein Datei-/Prozesszugriff aus PostScript), mit
Timeout (60 s je Seite, 10 min je Dokument, SIGKILL) und höchstens
500 gerenderten Seiten. Temp-Dateien werden auch im Fehlerfall
entfernt. Ungenutztes getPageCount (brauchte Dateizugriff) entfernt.
- Neuer Vorab-Check ueberschreitetDekompressionsLimit (256 MB, streamend,
erkennt auch Deflate-Ketten und abgeschnittene Streams). Fingerprint
(pdf.js) und E-Rechnungs-Extraktion (pdf-lib) laden Bomben nicht mehr;
eine einzelne Mail konnte das Backend sonst per OOM dauerhaft lahmlegen.
- Verschlüsselte PDFs bekommen keinen Inhalts-Fingerprint mehr ('' =
nicht vergleichbar), weil pdf.js sie erst intern entschlüsselt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
1.0 KiB
TypeScript
32 lines
1.0 KiB
TypeScript
import * as zlib from 'zlib';
|
||
import { PDFParse } from 'pdf-parse';
|
||
import { computeContentFingerprint } from './pdf-fingerprint.util';
|
||
|
||
jest.mock('pdf-parse', () => ({ PDFParse: jest.fn() }));
|
||
|
||
describe('computeContentFingerprint – ungeprüfte Inhalte', () => {
|
||
it('übergibt eine Deflate-Bombe nicht an pdf.js', async () => {
|
||
const bombe = zlib.deflateSync(Buffer.alloc(300 * 1024 * 1024));
|
||
const pdf = Buffer.concat([
|
||
Buffer.from(
|
||
`%PDF-1.7\n1 0 obj\n<< /Length ${bombe.length} /Filter /FlateDecode >>\nstream\n`,
|
||
'latin1',
|
||
),
|
||
bombe,
|
||
Buffer.from('\nendstream\nendobj\n%%EOF\n', 'latin1'),
|
||
]);
|
||
|
||
await expect(computeContentFingerprint(pdf)).resolves.toBe('');
|
||
expect(PDFParse).not.toHaveBeenCalled();
|
||
});
|
||
|
||
it('übergibt verschlüsselte PDFs nicht an pdf.js', async () => {
|
||
const pdf = Buffer.from(
|
||
'%PDF-1.7\ntrailer\n<< /Encrypt 5 0 R >>\n%%EOF\n',
|
||
'latin1',
|
||
);
|
||
await expect(computeContentFingerprint(pdf)).resolves.toBe('');
|
||
expect(PDFParse).not.toHaveBeenCalled();
|
||
});
|
||
});
|