From 7b2a79be2a167403aea45c1968a72432dec6a704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20P=C3=B6ttker?= Date: Wed, 22 Jul 2026 11:10:36 +0200 Subject: [PATCH] fix: Dateinamen mit Pfadtrennzeichen beim Mail-Import absichern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Anhänge mit '/' im Dateinamen (z.B. "Rechnung - 2026/002650322.PDF") führten zu einem Fehler, weil '/' als Verzeichnistrenner interpretiert wurde und der temp. Pfad nicht existierte. - sanitizeFilename() ersetzt '/' und '\' durch '-', entfernt '..' und Null-Bytes - Wird beim Speichern in die DB (email-download) und beim Aufbau des temp. Pfads (email-import) angewendet (defense-in-depth) Co-Authored-By: Claude Sonnet 4.6 --- .../src/email-download/email-download.service.ts | 10 +++++++++- paperless-backend/src/email/email-import.service.ts | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/paperless-backend/src/email-download/email-download.service.ts b/paperless-backend/src/email-download/email-download.service.ts index 5ff38cc..561a311 100644 --- a/paperless-backend/src/email-download/email-download.service.ts +++ b/paperless-backend/src/email-download/email-download.service.ts @@ -20,6 +20,14 @@ import { Attachment } from '../database/entities/attachment.entity'; import { Content } from '../database/entities/content.entity'; import { isERechnung } from './zugferd.util'; +function sanitizeFilename(name: string): string { + return name + .replace(/[/\\]/g, '-') + .replace(/\.\./g, '.') + .replace(/\x00/g, '') + .trim(); +} + @Injectable() export class EmailDownloadService { private readonly logger = new Logger(EmailDownloadService.name); @@ -291,7 +299,7 @@ export class EmailDownloadService { } const attachment = new Attachment(); - attachment.FileName = filename.slice(0, 255); + attachment.FileName = sanitizeFilename(filename).slice(0, 255); attachment.ContentType = contentType.slice(0, 100); attachment.IsEmbedded = isEmbedded; attachment.ContentId = att.cid ? att.cid.slice(0, 255) : null; diff --git a/paperless-backend/src/email/email-import.service.ts b/paperless-backend/src/email/email-import.service.ts index 884282b..76ab484 100644 --- a/paperless-backend/src/email/email-import.service.ts +++ b/paperless-backend/src/email/email-import.service.ts @@ -20,6 +20,14 @@ import * as os from 'os'; import * as fs from 'fs/promises'; import * as crypto from 'crypto'; +function sanitizeFilename(name: string): string { + return name + .replace(/[/\\]/g, '-') + .replace(/\.\./g, '.') + .replace(/\x00/g, '') + .trim(); +} + @Injectable() export class EmailImportService { private readonly logger = new Logger(EmailImportService.name); @@ -492,7 +500,7 @@ export class EmailImportService { if (!content) continue; const originalPdfBytes = content.Content1; - const baseFilename = attachmentEntity.FileName.replace(/\.pdf$/i, ''); + const baseFilename = sanitizeFilename(attachmentEntity.FileName.replace(/\.pdf$/i, '')); const paperlessIds: any = {}; const uploadPromises = [];