Skip to content
This repository was archived by the owner on Aug 22, 2026. It is now read-only.

Security review: clear all dependency vulnerabilities, harden chat API input - #3

Open
echotech wants to merge 1 commit into
mainfrom
claude/package-security-review-4hffqi
Open

Security review: clear all dependency vulnerabilities, harden chat API input#3
echotech wants to merge 1 commit into
mainfrom
claude/package-security-review-4hffqi

Conversation

@echotech

@echotech echotech commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Clears every known dependency advisory in the repo, which is what has been generating the daily Dependabot alert emails.

npm audit on main reports 4 high-severity vulnerable packages (next, postcss, nanoid, picomatch) spanning ~35 package/path/advisory pairs; GitHub currently counts 50 open alerts (21 high, 25 moderate, 4 low) across those same four packages. After this change, a clean npm ci + npm audit --audit-level=low reports 0 vulnerabilities.

Dependency changes

Package Before After Why
next 14.2 16.3.2 21 advisories. Not fully fixed until 15.5.21+, so a major upgrade was unavoidable.
react / react-dom 18.3 19.2.8 Required peer of Next 16.
@types/react / @types/react-dom 18.3 19.2.x Match React 19.
postcss 8.5.x 8.5.23 4 advisories (XSS via unescaped </style>, arbitrary .map file read via sourceMappingURL).
nanoid <3.3.18 3.3.18 2 infinite-loop advisories.
picomatch 2.3.1 / 4.0.3 2.3.2 / 4.0.5 ReDoS + method injection.

The Next.js advisories cleared include SSRF in rewrites and Server Actions, cache poisoning in RSC responses, App Router XSS with CSP nonces, unauthenticated disclosure of internal Server Function endpoints, and several DoS vectors.

tsconfig.json changes (moduleResolutionbundler, jsxreact-jsx, added .next/dev/types) were applied automatically by the Next 16 migration, not by hand.

No application source changes were required for the upgrade.

API hardening

Two issues found while reviewing app/api/chat/route.ts:

  • JSON.parse(body.disease) ran on caller-controlled input with no guard, so any malformed body threw and produced an unhandled 500. Now returns 400.
  • disease was interpolated into the model prompt with no length limit, letting an anonymous caller inflate token spend on the OpenAI key. Now capped at 500 characters.

Behaviour for valid requests is unchanged, including the existing ROLE_NOT_SET fallback for an unset physician type.

Verification

  • npm ci from the committed lockfile → npm audit --audit-level=low: 0 vulnerabilities
  • npm run build passes (compile, TypeScript, static generation) from a clean checkout
  • Production server smoke-tested: homepage renders 200, /api/chat streams correctly
  • Validation cases exercised: valid ✅ 200 · missing field / malformed JSON / empty body / null → 400 · 600-char input → 400 · 500-char input → 200
  • Browser-tested under React 19 (headless Chromium against next start), since 18 → 19 is the riskiest part of this change: page hydrates with zero React or hydration warnings, accordion state toggles, dropdown and controlled textarea work, and form submit issues POST /api/chat → 200. The only console error is a 404 for /_vercel/insights/script.js, which is the Vercel Analytics script that only exists on a Vercel deployment — pre-existing and unrelated.
  • No secrets found in the working tree or git history; no .env file has ever been committed

Not addressed — needs your decision

/api/chat is unauthenticated and has no rate limiting. This is the largest remaining exposure: anyone can call it in a loop and bill GPT-4 usage to your OpenAI key. The length cap above narrows the per-request cost but does nothing about request volume. Fixing it properly means adding a rate limiter (e.g. @upstash/ratelimit backed by Upstash Redis, which is what the upstream template used) plus the accompanying infrastructure, so I left it out rather than adding a dependency and an external service on my own.

Two lower-priority items also left alone:

  • next.config.js still redirects /github and /deploy to Nutlope/twitterbio and an unrelated Vercel template — leftover from the starter this was forked from. Not a vulnerability (destinations are fixed, not attacker-controlled), but they point users of your domain at an unrelated project.
  • app/layout.tsx has a malformed metadataBase: new URL('https://https://med-notes-...'). A correctness bug in OG/Twitter card URLs, not a security issue.

One note on the upgrade itself: Next 16 deprecates the Edge runtime that /api/chat uses (export const runtime = 'edge'). It still works and the build only warns, but it will need migrating to nodejs eventually.

npm audit reported 4 high-severity advisories (nanoid, next, picomatch,
postcss) covering 20+ CVEs, which is what has been generating the daily
Dependabot alert emails. This clears all of them: npm audit now reports
0 vulnerabilities.

Dependencies:
- next 14.2 -> 16.3.2. The Next.js advisories (SSRF in rewrites and Server
  Actions, cache poisoning, App Router XSS via CSP nonces, several DoS
  vectors, unauthenticated disclosure of Server Function endpoints) are only
  fully resolved in 15.5.21+, so a major upgrade was required.
- react / react-dom 18.3 -> 19.2.8, required by Next 16.
- @types/react and @types/react-dom bumped to match React 19.
- postcss resolves to 8.5.23, nanoid to 3.3.18, picomatch to 2.3.2/4.0.5.
- tsconfig.json: moduleResolution and jsx updated by the Next 16 migration.

No application source changes were needed for the upgrade; the build,
static generation, and the streaming chat route all work unchanged.

API hardening (found during the review):
- POST /api/chat called JSON.parse on caller-controlled input with no guard,
  so any malformed body produced an unhandled 500. It now returns 400.
- The disease field was forwarded to the model with no length limit, letting
  an anonymous caller run up token cost on our API key. Now capped at 500
  characters.

Note: /api/chat remains unauthenticated and unrated-limited, which is the
largest remaining exposure. That needs a rate limiter and is left out of
this change deliberately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EfzXHE5YUHyMmdWfm39xz6
@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
med-notes Error Error Aug 22, 2026 3:21am

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants