Skip to content

Harden server: compression, CSP, rate limits, gold guard, DB indexes#176

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

Harden server: compression, CSP, rate limits, gold guard, DB indexes#176
Sparksx wants to merge 1 commit into
mainfrom
claude/focused-curie-oe2qzn

Conversation

@Sparksx

@Sparksx Sparksx commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Summary

Quick-win improvements from a full codebase audit across security, performance, stability, and functionality. These are the highest-impact, lowest-effort changes identified.

  • Security: Enable Content-Security-Policy — CSP was completely disabled (contentSecurityPolicy: false). Now active with directives tailored to the game (Stripe checkout, OAuth providers, WebSocket, inline styles).
  • Security: Gold guard on game state savePUT /api/game/state no longer allows the client to inflate gold. The server compares submitted gold against the DB and silently caps it, closing the main cheat vector.
  • Security: Stricter rate limits — Dedicated limiters for payment endpoints (10 req/min) and game-state save (30 req/min), on top of the existing global 100 req/min.
  • Performance: HTTP compression — Added compression middleware (gzip). All REST responses are now compressed (~60-70% size reduction on JSON payloads).
  • Performance: Database indexes — Added indexes on ChatMessage.senderId, Purchase(userId, status), and Purchase.stripePaymentId for faster lookups on growing tables.
  • Stability: Fix competing shutdown handlers — Removed the SIGINT/SIGTERM handlers in prisma.js that raced with the graceful shutdown in index.js, causing premature process.exit() before HTTP connections drained.
  • Stability: Real health check/api/health now verifies DB connectivity and reports memory/uptime. Returns 503 when the database is unreachable, so Railway can detect a degraded backend.

Test plan

  • npm test — 524 tests pass (no regressions)
  • npm run build — production build succeeds
  • npm run lint — no new errors (only pre-existing warnings)
  • Verify CSP does not block game assets or Stripe checkout in production
  • Verify compression headers (Content-Encoding: gzip) on API responses
  • Confirm gold guard logs warnings when a crafted request tries to inflate gold

Generated by Claude Code

… health check

Security:
- Enable Content-Security-Policy via Helmet (was disabled) with directives
  tailored to the game (Stripe, OAuth providers, WebSocket, inline styles)
- Add gold guard on PUT /api/game/state: client can only decrease gold,
  never inflate it — server-granted gold (expeditions, Stripe) is protected
- Add stricter rate limiters for payment (10/min) and save (30/min) endpoints

Performance:
- Add compression middleware (gzip) for all HTTP responses
- Add DB indexes on ChatMessage.senderId, Purchase(userId+status),
  Purchase.stripePaymentId for faster lookups on growing tables

Stability:
- Remove competing SIGINT/SIGTERM handlers in prisma.js that raced with
  the graceful shutdown in index.js and called process.exit() prematurely
- Upgrade /api/health to verify DB connectivity and report memory/uptime,
  so Railway detects a degraded backend instead of returning false-ok

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