Skip to content

fix: sanitize input for non-HTML consumers and fix ReDoS in cache - #62

Merged
mmcintosh merged 1 commit into
mainfrom
security/route-input-sanitization
Feb 25, 2026
Merged

mmcintosh merged 1 commit into
mainfrom
security/route-input-sanitization

Conversation

@mmcintosh

Copy link
Copy Markdown
Owner

Description

Add input sanitization for fields served to non-HTML consumers (JWT payloads, JSON API responses, email subjects) and fix a ReDoS vulnerability in cache pattern invalidation. This is PR 3 in the AUDIT-001 remediation series.

Strategy: Input sanitization is applied only to fields consumed outside HTML templates (where PR 1's output escaping handles XSS). This prevents double-encoding.

Changes

Auth Registration Sanitization (auth.ts)

  • POST /register: sanitize username, firstName, lastName (returned in JWT and API response)
  • POST /register/form: sanitize same fields
  • POST /accept-invitation: sanitize username
  • Skipped: email (Zod-validated), password (hashed, never sanitize)

Media API Sanitization (api-media.ts)

  • PATCH /:id: sanitize alt and caption fields (returned in JSON API responses via GET /api/media/:id)

Email Template Subject (email-templates-plugin/admin-routes.ts)

  • POST /templates: sanitize subject field (rendered as plain text in email clients)

ReDoS Fix (cache/services/cache.ts)

  • MemoryCache.invalidatePattern() and CacheService.invalidate(): escape regex metacharacters (.+|()[]{}^$\) before glob-to-regex conversion
  • Previously, patterns like (a+)+* could cause catastrophic backtracking

Testing

Build Verification

  • ESM build passes
  • CJS build passes
  • DTS (TypeScript declarations) build passes

E2E Tests

  • Full E2E suite (CI)

Technical Details

4 source files changed:

File Change
src/routes/auth.ts sanitizeInput() on username/firstName/lastName in 3 handlers
src/routes/api-media.ts sanitizeInput() on alt/caption in PATCH handler
src/plugins/available/email-templates-plugin/admin-routes.ts sanitizeInput() on subject
src/plugins/cache/services/cache.ts Escape regex metacharacters in 2 locations

Breaking Changes

None. Registration fields with HTML characters will now be stored escaped. Media alt/caption will be stored escaped.

Checklist

  • Code follows project conventions
  • Type checking passes
  • No console errors or warnings

Generated with Claude Code in Conductor

@codecov

codecov Bot commented Feb 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@mmcintosh
mmcintosh force-pushed the security/route-input-sanitization branch from 6029fcf to 2458c9a Compare February 25, 2026 12:54
@mmcintosh
mmcintosh merged commit 1fcf3f0 into main Feb 25, 2026
2 of 3 checks passed

This branch was previously deployed

1 inactive deployment
internal — 2458c9a4 Deployed Feb 25, 2026 by mmcintosh via authorize #394
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant