Harden security, performance, and stability (quick wins) - #192
Open
Sparksx wants to merge 1 commit into
Open
Conversation
Security: - Enable Content Security Policy (CSP) with directives for self, Stripe, and WebSocket - Use distinct JWT dev fallback secrets to prevent access/refresh token confusion - Pin JWT verification to HS256 algorithm (defense-in-depth) - Add rate limiting on the /refresh endpoint to prevent token abuse - Limit settings payload size (4KB max, 20 keys max) - Add username character-set validation (alphanumeric + underscore/dash only) Performance: - Cache Stripe SDK instance as singleton instead of re-creating per request - Add database index on RefreshToken.expiresAt for periodic cleanup queries - Add Cache-Control header on monster templates (matching equipment/player templates) - Serve Vite hashed assets with immutable cache headers (1 year max-age) - Remove unnecessary save() call from trashItem (no state mutation occurs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0184XFRfwnkhdecjbHTgvMwV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Comprehensive codebase audit across security, performance, stability, and functionality — with immediate implementation of the highest-priority quick wins (low difficulty, high impact).
Security fixes
contentSecurityPolicy: false), now configured with proper directives for self, Stripe JS/API, WebSocket, and dev localhostJWT_SECRETandJWT_REFRESH_SECRETshared the same fallback value, meaning an access token could be verified as a refresh token in devjwt.verify()calls now explicitly restrict toHS256, preventing algorithm confusion attacks/refreshendpoint — was the only auth endpoint without rate limiting, enabling unlimited token generation from a stolen refresh tokenPUT /api/auth/settingsaccepted arbitrary JSON with no size cap; now limited to 20 keys / 4KB[A-Za-z0-9_-]to prevent homoglyph impersonation and unicode abusePerformance fixes
new Stripe(...)was called on every payment request; now cached as a lazy singletonRefreshToken.expiresAt— the 24h cleanup query was doing a full table scanmax-age=3600/assets/*files now served withmax-age=1y, immutablesave()fromtrashItem— the function emitted events but triggered a wasted localStorage write + server save despite not modifying stateAudit findings (remaining backlog)
The full audit identified additional improvements not implemented in this PR, ordered by priority:
completeMission(double-complete possible)broadcastConversationiterates all connected socketsMath.random()in transaction (non-deterministic on retry)Test plan
npm test)npm run build)/refreshuses same 5/min window as other auth endpoints_and-Generated by Claude Code