Skip to content

fix: critical bugs in comments, likes, and Convex mutation auth#108

Draft
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-investigation-84b9
Draft

fix: critical bugs in comments, likes, and Convex mutation auth#108
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-investigation-84b9

Conversation

@cursor
Copy link
Copy Markdown

@cursor cursor Bot commented Jun 1, 2026

Summary

Daily critical-bug investigation found three unfixed issues on main (fixes existed on unmerged branches). This PR applies minimal, high-confidence patches.

Bugs fixed

1. Comment thread orphans (user-facing)

Impact: On busy pages, comments.list took the top 200 comments by score. A high-scoring reply could be included while its lower-scored parent was dropped, so the UI showed a false [deleted] parent.

Root cause: Flat slice(0, MAX_COMMENTS) without pulling in ancestors.

Fix: When selecting top comments, always include the ancestor chain for each selected reply.

2. Inflated like counts (user-facing)

Impact: Parallel setLike races could insert duplicate likes rows for one visitor. Reads counted rows (not unique visitors), and dedup decrements desynced the denormalized counter.

Root cause: Row-count semantics + increment/decrement per duplicate row.

Fix: Count distinct ipHash values; syncLikeCountForUrl after each mutation; backfill rebuilds per-URL totals from unique visitors.

3. Convex write auth bypass (security)

Impact: Public mutations accepted arbitrary ipHash, so direct ConvexHttpClient calls could bypass per-IP bans, rate limits, and inflate likes.

Root cause: Trusting client-supplied ipHash with no server attestation.

Fix: SvelteKit API routes attach ipProof (HMAC of ipHash with IP_HASH_SECRET); mutations verify via assertIpProof (admin bypass unchanged).

4. Series navigation reload

Impact: Active series item used href="", reloading the page on click.

Fix: Render current item as a non-link; use absolute /blog/{slug} hrefs for siblings.

Deploy notes

After merge, set Convex env (same value as Vercel):

npx convex env set IP_HASH_SECRET "$IP_HASH_SECRET"

Without this, legitimate writes will fail with Forbidden once Convex functions deploy.

Validation

  • Code review + logic trace against known fixes on dcf7ab6, b2dc165, e36feda
  • Added scripts/ip-proof-test.mjs and scripts/like-unique-count-test.mjs (require live Convex/dev server)
  • npm run check — pre-existing errors only (no new files in changed Svelte components)
Open in Web View Automation 

- comments.list: include ancestors when selecting top-N by score so
  high-scoring replies no longer appear with a false deleted parent
- likes: count distinct ipHashes and sync denormalized counter after
  each mutation (fixes inflated counts from duplicate race rows)
- security: require HMAC ipProof on public write mutations so direct
  Convex calls cannot forge ipHash to bypass bans/rate limits
- SeriesList: stop empty href reload on the active series item

Co-authored-by: Injoon Oh <injoon5@icloud.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

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

Project Deployment Actions Updated (UTC)
web Ready Ready Preview, Comment Jun 1, 2026 3:08pm

@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying web with  Cloudflare Pages  Cloudflare Pages

Latest commit: 98205f7
Status:🚫  Build failed.

View logs

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