fix: magic-byte upload validation, CSP headers, upgrade xmldom

🟢 open · #78 · willchen96/mike ← bmersereau/mike · opened 14d ago by bmersereau · +1,398-12 across 9 files · ↗ on GitHub

From the PR description

Summary

  • Adds magic-byte (file signature) validation to both upload paths - initial document upload and version upload - rejecting files whose bytes don't match their declared extension
  • Enables a Content-Security-Policy in the backend via helmet and adds CSP + X-Frame-Options headers to the Next.js frontend
  • Upgrades @xmldom/xmldom to ≥ 0.8.13 via npm overrides to patch 4 high-severity CVEs (GHSA-2v35, GHSA-f6ww, GHSA-x6wf, GHSA-j759)

Closes #69 Closes #84 Closes #92

Changes

  • backend/src/lib/magicBytes.ts - validateMagicBytes(buf, ext) helper with signatures for pdf/docx/doc
  • backend/src/routes/documents.ts - magic-byte check in initial-upload and version-upload paths
  • backend/src/index.ts - CSP enabled via helmet (default-src 'self', object-src 'none', frame-ancestors 'none')
  • frontend/next.config.ts - CSP + X-Frame-Options headers via headers() export; unsafe-eval gated to development only
  • backend/package.json - xmldom override pinned to ≥0.8.13; vitest added
  • backend/src/lib/__tests__/magicBytes.test.ts - 7 unit tests

Test plan

  • Unit tests: valid PDF/DOCX/DOC accepted, HTML-disguised file rejected, empty/short buffers rejected, unknown ext rejected
  • Backend and frontend build + typecheck pass

Our analysis

Harden document uploads against XSS and tighten CSP — read the full analysis →

Think the analysis missed something the PR description covers?

Capture this PR into my fork

Download a Markdown prompt that tells Claude how to port every commit in this PR into your working tree. Run it via claude -p < capture-pull-78.md from inside the repo you want the changes in.

⬇ Download capture-pull-78.md