Skip to content

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

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

fix: sanitize input for non-HTML consumers and fix ReDoS in cache#62
mmcintosh merged 1 commit intomainfrom
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
Copy link
Copy Markdown

codecov bot commented Feb 24, 2026

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
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