Security: update Express 4.x stack and clear critical/high advisories #13

Merged
backmeupplz merged 2 commits from security/express-4.21 into master 2026-10-23 00:05:06 +00:00
Owner

Security update for pay.voicybot.com. It replaces the 2016-era Express stack and clears the rest of the critical/high advisories. osv-scanner: 106 vulnerabilities → 7 (6 moderate, 1 low), with no critical or high left.

Changes

Express stack (first commit, prepared with a subagent):

  • express ~4.13.1 → ^4.21.2 (resolves 4.22.3; stays on 4.x, so no Express 5 breaking changes)
  • body-parser (direct dep) ~1.13.2 → ^1.20.3 (1.20.9)
  • Removed unused serve-favicon: it was never required, and it was the last source of the vulnerable fresh@0.3.0. fresh is now 0.5.2.
  • npm override qs ^6.16.1 (a single deduped copy)
  • Regenerated package-lock.json and deleted the stale yarn.lock (it still pinned mongoose 4)

Remaining critical/high (second commit):

  • morgan ~1.6.1 → ^1.10.0 (1.12.1) and debug ~2.2.0 → ^2.6.9: both are loaded by the web entrypoint
  • lodash ^4.17.21 → ^4.17.23 (4.18.1)
  • npm overrides: form-data ^2.5.5 (via request), json-schema ^0.4.0 (via jsprim), semver ^5.7.2 (via require_optional)

Advisories closed include fresh ReDoS GHSA-9qj9-36jm-prpv, qs GHSA-hrpp-h998-j3pp (CVE-2022-24999) plus the newer qs DoS advisories, body-parser, express, send, serve-static, path-to-regexp, morgan, debug, form-data, json-schema and semver.

Deploy path

Easypanel builds this with railpack + npm ci, so package-lock.json is what ships (nixpacks.toml is no longer used). npm ci --omit=dev succeeds on this branch.

Testing

I tested against a throwaway MongoDB 8.0, which is what voicy-db runs since today's migration, on Node 22:

  • node ./bin/www starts ("Server is up and running", "New stats were generated!")
  • GET /statsforashmanov → 200, GET /statsfornikita → 200 (res.json)
  • ETag + If-None-Match → 304 (exercises fresh 0.5.2)
  • GET / → 404, same as before (there is no route for /)

There is no server-side Stripe webhook or raw-body signature check anywhere (payments are retired), so the body-parser bump has nothing of that kind to break.

🤖 Generated with Claude Code

Security update for pay.voicybot.com. It replaces the 2016-era Express stack and clears the rest of the critical/high advisories. osv-scanner: **106 vulnerabilities → 7 (6 moderate, 1 low), with no critical or high left.** ## Changes **Express stack** (first commit, prepared with a subagent): - express ~4.13.1 → ^4.21.2 (resolves 4.22.3; stays on 4.x, so no Express 5 breaking changes) - body-parser (direct dep) ~1.13.2 → ^1.20.3 (1.20.9) - Removed unused `serve-favicon`: it was never required, and it was the last source of the vulnerable fresh@0.3.0. fresh is now 0.5.2. - npm override `qs` ^6.16.1 (a single deduped copy) - Regenerated package-lock.json and deleted the stale yarn.lock (it still pinned mongoose 4) **Remaining critical/high** (second commit): - morgan ~1.6.1 → ^1.10.0 (1.12.1) and debug ~2.2.0 → ^2.6.9: both are loaded by the web entrypoint - lodash ^4.17.21 → ^4.17.23 (4.18.1) - npm overrides: form-data ^2.5.5 (via request), json-schema ^0.4.0 (via jsprim), semver ^5.7.2 (via require_optional) Advisories closed include fresh ReDoS GHSA-9qj9-36jm-prpv, qs GHSA-hrpp-h998-j3pp (CVE-2022-24999) plus the newer qs DoS advisories, body-parser, express, send, serve-static, path-to-regexp, morgan, debug, form-data, json-schema and semver. ## Deploy path Easypanel builds this with **railpack + `npm ci`**, so package-lock.json is what ships (nixpacks.toml is no longer used). `npm ci --omit=dev` succeeds on this branch. ## Testing I tested against a throwaway **MongoDB 8.0**, which is what voicy-db runs since today's migration, on Node 22: - `node ./bin/www` starts ("Server is up and running", "New stats were generated!") - `GET /statsforashmanov` → 200, `GET /statsfornikita` → 200 (`res.json`) - ETag + `If-None-Match` → 304 (exercises fresh 0.5.2) - `GET /` → 404, same as before (there is no route for `/`) There is no server-side Stripe webhook or raw-body signature check anywhere (payments are retired), so the body-parser bump has nothing of that kind to break. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Bump express ~4.13.1 -> ^4.21.2 (resolves to 4.22.3) and the direct
body-parser dep ~1.13.2 -> ^1.20.3. This pulls the fixed transitive
Express stack: fresh 0.5.2, qs 6.16.1, send 0.19.2, serve-static 1.16.3,
path-to-regexp 0.1.13 and cookie 0.7.2.

Add an npm "overrides" of qs ^6.16.1 so the copies dragged in by request
(node-telegram-bot-api) and stripe also resolve to 6.16.1, and drop the
unused serve-favicon dependency, which was the only remaining source of
the vulnerable fresh 0.3.0 (it is never required anywhere; favicons are
served from public/ via express.static).

Regenerate package-lock.json, the source of truth the deploy actually
uses (nixpacks runs `npm install`), and delete the stale yarn.lock, which
had not been updated since before the mongoose 4 -> 6 upgrade and no
longer matched package.json; the repo and deploy are npm-only.

No app behavior change: the only routes are GET /statsfornikita and
/statsforashmanov (both res.json), there is no Stripe webhook / raw-body
signature path, and body-parser json/urlencoded usage is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Clears the critical/high advisories left after the Express update:
morgan 1.6.1 -> 1.12.1 and debug 2.2.0 -> 2.6.9 (both loaded by the web
entrypoint), lodash 4.17.21 -> 4.18.1, and npm overrides for form-data
2.5.6, json-schema 0.4.0 and semver 5.7.2 (pulled in by request, jsprim
and require_optional).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
backmeupplz deleted branch security/express-4.21 2026-10-23 00:05:06 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
backmeupplz/voicy-payments!13
No description provided.