Four request-hardening primitives wired into Express

Dshamir adds Zod validation, Pino structured logging, GlitchTip/Sentry error tracking, magic-byte MIME validation, and a strict Helmet CSP to the Express backend - all as self-contained modules that drop in without touching route logic.

securityinfrastructure

The MIME validator (upload.ts) reads the first bytes of every uploaded file with file-type, checks the detected MIME against an allowlist (application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/msword), and rejects anything else. A renamed executable claiming to be a PDF gets rejected at the buffer level, not based on the extension. One edge case: .doc files return no detected type, so the validator treats them as valid - a deliberate fallback for old-format Word documents.

The Pino logger (logger.ts) redacts req.headers.authorization, req.headers.cookie, and any field named password, secret, apiKey, api_key, or encrypted_key. The requestId middleware attaches res.locals.log as a child logger keyed to the request ID so every log line from a given request shares the same requestId field. All console.* calls across the route layer were replaced with logger.info/debug/error calls.

The error handler (errorHandler.ts) intercepts ZodErrors and returns RFC 7807 problem-detail responses: { type: "validation_error", title: "Invalid request", status: 400, errors: [...] }. Unhandled errors get { type: "server_error", status: 500 }, with the actual message visible in development and a generic string in production. GlitchTip/Sentry receives a captureException call on every 500.

The Zod validation middleware (validation.ts) takes a schema and calls schema.parse({ body, query, params }). It's nine lines. The common.ts schema file exports zodUUID, zodNonEmptyString, zodPagination, zodParamsWithId, and zodParamsWithProjectId - the shared building blocks reused throughout the fork's later route-validation work.

The CSP is strict: default-src 'self', script-src 'self', object-src 'none', frame-ancestors 'none'. style-src allows 'unsafe-inline' (common Next.js constraint), and connect-src includes the FRONTEND_URL env var for cross-origin SSE.

So what Worth importing. The MIME validator, Pino logger with redaction, and RFC 7807 error handler are each small, clean, and independent. The `validate()` middleware and `common.ts` schemas are useful regardless of whether you adopt the rest of the fork. Skip if you have equivalent tooling already in place.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

6 commits from Dshamir/AI-Legal, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
d13c77a3 [P2] chore: add zod, pino, sentry, file-type dependencies Dshamir 2026-05-23 ↗ GitHub
46efac39 [P2] feat: add magic-byte MIME validation for uploads Dshamir 2026-05-23 ↗ GitHub
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
440da990 [P2] feat: add Pino structured logger with redaction and request ID middleware Dshamir 2026-05-23 ↗ GitHub
Add structured logging via Pino with sensitive field redaction and
per-request child loggers tied to X-Request-ID headers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
caf82b04 [P2] feat: add GlitchTip/Sentry error tracking and global error handler Dshamir 2026-05-23 ↗ GitHub
commit body
Add error tracking initialization with GlitchTip/Sentry and a global
Express error handler producing RFC 7807 problem detail responses with
Zod validation error formatting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
25e099b1 [P2] feat: add Zod validation framework and common schemas Dshamir 2026-05-23 ↗ GitHub
Add Express middleware for Zod schema validation and reusable common
schemas for UUIDs, pagination, and route params.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7f2aa547 [P2] feat: wire validation, logging, error handling, CSP into Express Dshamir 2026-05-23 ↗ GitHub
commit body
- Add requestId, globalErrorHandler middleware to Express pipeline
- Initialize error tracking (GlitchTip/Sentry) before app setup
- Enable CSP via Helmet with strict directives
- Replace all console.log/error/warn with Pino structured logger
- Fix file-type ESM module resolution with @ts-ignore

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-520.md from inside the repo you want the changes in.

⬇ Download capture-thread-520.md