Fixes a path-traversal arbitrary-file-write vulnerability (CWE-22/CWE-73) in event-image, branding (logo/favicon), and event-attachment uploads — the stored filename embedded the unsanitized client-supplied original filename, allowing ../ sequences to escape the upload directory. Filenames are now always server-generated.
Patches all known-vulnerable dependencies across root/backend/frontend (npm audit now clean everywhere), including a critical unauthenticated Next.js RCE (GHSA-9qr9-h5gf-34mp) and moving express-rate-limit into backend/package.json (it was root-only, so a standalone cd backend && npm install never installed it).
Hardening: jwt.verify() now pins algorithms: ['HS256']; /uploads now serves with a restrictive CSP + X-Content-Type-Options: nosniff to neutralize SVG-embedded-script XSS.
Version bumped to 1.10.1, tagged v1.10.1.
Test plan
Backend Jest suite (21 tests) passes on the bumped dependencies
Backend boots and serves real HTTP requests on the bumped deps; confirmed CSP/nosniff headers present on real uploaded files
next build compiles and type-checks cleanly on the bumped frontend deps (verified against a live backend + real event data)
npm audit reports 0 vulnerabilities in root, backend, and frontend
## Summary
- Fixes a path-traversal arbitrary-file-write vulnerability (CWE-22/CWE-73) in event-image, branding (logo/favicon), and event-attachment uploads — the stored filename embedded the unsanitized client-supplied original filename, allowing `../` sequences to escape the upload directory. Filenames are now always server-generated.
- Patches all known-vulnerable dependencies across root/backend/frontend (`npm audit` now clean everywhere), including a critical unauthenticated Next.js RCE (GHSA-9qr9-h5gf-34mp) and moving `express-rate-limit` into `backend/package.json` (it was root-only, so a standalone `cd backend && npm install` never installed it).
- Hardening: `jwt.verify()` now pins `algorithms: ['HS256']`; `/uploads` now serves with a restrictive CSP + `X-Content-Type-Options: nosniff` to neutralize SVG-embedded-script XSS.
- Version bumped to 1.10.1, tagged `v1.10.1`.
## Test plan
- [x] Backend Jest suite (21 tests) passes on the bumped dependencies
- [x] Backend boots and serves real HTTP requests on the bumped deps; confirmed CSP/`nosniff` headers present on real uploaded files
- [x] `next build` compiles and type-checks cleanly on the bumped frontend deps (verified against a live backend + real event data)
- [x] `npm audit` reports 0 vulnerabilities in root, backend, and frontend
https://claude.ai/code/session_01CSWFWQsjTc9GyffPiXEDQT
Path traversal (CWE-22/CWE-73): event-image, branding (logo/favicon),
and event-attachment uploads built the saved filename from the
client-supplied original filename with no sanitization, and multer's
diskStorage joins that straight into the destination path. A crafted
filename containing `../` sequences could write the uploaded file
anywhere the server process has write access — reachable by any
supervisor-level account, and briefly pre-auth via the branding
uploads during initial /setup. Filenames are now always server-
generated (random bytes + validated extension); the original name is
kept only as display metadata.
Dependencies: express-rate-limit was declared only at the repo root
despite being required directly by backend/src/index.js, so a plain
`cd backend && npm install` (per the deployment doc) would never
install it — moved it into backend/package.json. Bumped next off a
version affected by a critical unauthenticated RCE (React Flight
protocol) and switched it from an exact pin to a caret range so future
patches install automatically. Bumped multer/nodemailer/jsonwebtoken/
uuid to patched versions, with an override forcing the vulnerable
nested uuid inside exceljs and the vulnerable postcss bundled inside
next to the patched versions too. `npm audit` is now clean (0
vulnerabilities) across root, backend, and frontend.
Hardening: jwt.verify() now pins algorithms: ['HS256'] instead of
trusting the token header; /uploads now serves with a restrictive CSP
and X-Content-Type-Options: nosniff so an uploaded SVG containing
<script> can't execute if opened directly.
Verified: backend's Jest suite passes, the backend boots and serves
real requests on the bumped deps, and `next build` compiles/type-
checks cleanly on the bumped frontend deps.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSWFWQsjTc9GyffPiXEDQT
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
../sequences to escape the upload directory. Filenames are now always server-generated.npm auditnow clean everywhere), including a critical unauthenticated Next.js RCE (GHSA-9qr9-h5gf-34mp) and movingexpress-rate-limitintobackend/package.json(it was root-only, so a standalonecd backend && npm installnever installed it).jwt.verify()now pinsalgorithms: ['HS256'];/uploadsnow serves with a restrictive CSP +X-Content-Type-Options: nosniffto neutralize SVG-embedded-script XSS.v1.10.1.Test plan
nosniffheaders present on real uploaded filesnext buildcompiles and type-checks cleanly on the bumped frontend deps (verified against a live backend + real event data)npm auditreports 0 vulnerabilities in root, backend, and frontendhttps://claude.ai/code/session_01CSWFWQsjTc9GyffPiXEDQT