Secure file uploads in Express
This is the canonical Express integration path for Pompelmi.
Use it when you already accept files through Multer and want a clear allow, quarantine, or reject decision before writing anything to disk or object storage.
For the longer reasoning behind this route shape, see How to Scan File Uploads in Express Before Storage.
Install
Section titled “Install”npm install pompelmi @pompelmi/express-middleware express multerMinimal route
Section titled “Minimal route”import express from 'express';import multer from 'multer';import { createUploadGuard } from '@pompelmi/express-middleware';import { CommonHeuristicsScanner, composeScanners, createZipBombGuard,} from 'pompelmi';
const app = express();
const scanner = composeScanners( [ ['zipGuard', createZipBombGuard()], ['heuristics', CommonHeuristicsScanner], ], { stopOn: 'suspicious' });
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 10 * 1024 * 1024 },});
app.post( '/upload', upload.single('file'), createUploadGuard({ scanner, includeExtensions: ['pdf', 'png', 'jpg', 'jpeg', 'zip'], allowedMimeTypes: [ 'application/pdf', 'image/png', 'image/jpeg', 'application/zip', ], maxFileSizeBytes: 10 * 1024 * 1024, failClosed: true, }), (req, res) => { const scan = (req as any).pompelmi;
if (!req.file) { return res.status(400).json({ error: 'No file provided' }); }
if (scan?.verdict !== 'clean') { return res.status(422).json({ ok: false, verdict: scan?.verdict, results: scan?.results ?? [], }); }
res.json({ ok: true, verdict: 'clean', file: req.file.originalname }); });Why this pattern
Section titled “Why this pattern”multer.memoryStorage()keeps bytes in memory until the route has a verdict.createUploadGuard()gives Express a real upload gate instead of ad hoc checks inside the handler.createZipBombGuard()covers archive-specific abuse that a MIME allowlist cannot see.CommonHeuristicsScanneradds structural checks for PDFs, SVGs, Office files, executables, and EICAR-like test content.
Production notes
Section titled “Production notes”- Keep parser limits and
maxFileSizeBytesaligned. - Treat
suspiciousas quarantine or manual review for document-heavy workflows. - Store files only after the route returns
clean. - Add auth, rate limits, and non-executable storage outside the scanner itself.