Skip to content

Harden security, stability, and performance (quick wins) - #174

Open
Sparksx wants to merge 1 commit into
mainfrom
claude/focused-curie-t6gdbe
Open

Harden security, stability, and performance (quick wins)#174
Sparksx wants to merge 1 commit into
mainfrom
claude/focused-curie-t6gdbe

Conversation

@Sparksx

@Sparksx Sparksx commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

Full-stack analysis of the game across security, stability, performance, and functionality — followed by implementation of the highest-priority quick wins (high impact, low risk).

Security

  • Anti-cheat: cap gold increases per save — The PUT /api/game/state endpoint was fully client-authoritative for gold. A player could send { gold: 999999 } and bypass Stripe purchases entirely. Now rejects gold increases exceeding 500 per save (legitimate boss/forge rewards are tiny: 10–50g).
  • Drop dead currency fields — Removed acceptance of diamonds, essence, skills, research, shopState from the state save endpoint. These are dormant systems that were needlessly exposed.
  • Enable Content Security Policy — CSP was completely disabled (contentSecurityPolicy: false). Now configured with proper directives allowing Google/Stripe/Discord integrations while blocking XSS payloads.
  • Rate limit payment endpoints — Added a dedicated 5 req/min limiter on /create-checkout-session and /confirm to prevent Stripe API abuse.
  • Atomic purchase credit & refundcreditPurchase and the refund clawback now run inside $transaction blocks, preventing race conditions where gold could be double-credited or the clawback could be overwritten by a concurrent client save.

Stability

  • Atomic clan leave — Clan leave + ownership transfer was a multi-step non-transactional sequence. Two simultaneous leaves could corrupt ownership or orphan clans. Now wrapped in an interactive transaction.
  • Atomic admin resource edits — Admin gold/essence/diamond adjustments used read-compute-write without transactions. A concurrent client save could overwrite the admin's change. Now transactional.
  • Remove duplicate shutdown handlersprisma.js and index.js both registered SIGTERM/SIGINT handlers that raced each other. Removed the prisma.js handlers; index.js owns the full shutdown sequence.
  • Reliable save on tab closebeforeunload save used bare fetch() which browsers may kill before completion. Now uses fetch with keepalive: true for reliable delivery.

Performance

  • Lightweight clan listingGET /api/clans was loading full member rosters (equipment JSON, player data) for all 25 clans. Now fetches only _count.members, reducing payload from potentially 1MB+ to a few KB.

Test plan

  • All 308 existing tests pass (npm test)
  • Lint clean — 0 new warnings (npm run lint)
  • Production build succeeds (npm run build)
  • Verify clan list loads correctly (lighter payload, no member details)
  • Verify game state saves work normally (gold accepted within threshold)
  • Verify payment checkout flow still works with rate limiter
  • Verify clan leave as owner correctly transfers ownership
  • Verify admin gold/essence/diamond adjustments persist correctly

🤖 Generated with Claude Code

https://claude.ai/code/session_01AKMRqzDdMm76d4zHUNhFn5


Generated by Claude Code

Security:
- Cap gold increases per save to prevent client-side gold injection (anti-cheat)
- Drop dead currency fields (diamonds/essence/skills/research) from state save
- Enable Content Security Policy via helmet
- Add dedicated rate limiter on payment endpoints (5/min)
- Wrap creditPurchase and refund clawback in transactions (atomicity)

Stability:
- Wrap clan leave + ownership transfer in an interactive transaction
- Use transactional read-compute-write for admin gold/essence/diamond edits
- Remove duplicate SIGTERM/SIGINT handlers from prisma.js (index.js owns shutdown)
- Use fetch keepalive for beforeunload save flush (survives page teardown)

Performance:
- Use lightweight include (member count only) for clan list endpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AKMRqzDdMm76d4zHUNhFn5
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.

2 participants