Problem
Two security misconfigurations in the backend:
-
trustProxy: true (src/index.ts:34) — Fastify takes the leftmost X-Forwarded-For value, which the client controls. All IP-based rate limits (IP_RATE_LIMIT_MAX, etc.) can be bypassed by sending a fake header.
-
CORS not configured — In production without CORS_ALLOWED_ORIGINS, @fastify/cors registers with origin: false. The APK uses fetch/axios from WebView (not CapacitorHttp plugin), so CORS applies. Without the header, the WebView discards responses. The app is either broken or relies on a manual Render dashboard config not in the repo.
Impact
- Rate limiting completely bypassable via header spoofing
- App may not communicate with API correctly in production
- CORS misconfiguration can leak data or allow unauthorized access
Proposed Fix
- Change
trustProxy: true to trustProxy: 1 (single proxy hop)
- Set
CORS_ALLOWED_ORIGINS=https://localhost,capacitor://localhost,http://localhost as default
- Document the CORS configuration requirement in README
Files to modify
micopay/backend/src/index.ts (line 34)
micopay/backend/src/config.ts (lines 35-44)
Acceptance Criteria
Problem
Two security misconfigurations in the backend:
trustProxy: true (
src/index.ts:34) — Fastify takes the leftmost X-Forwarded-For value, which the client controls. All IP-based rate limits (IP_RATE_LIMIT_MAX, etc.) can be bypassed by sending a fake header.CORS not configured — In production without
CORS_ALLOWED_ORIGINS, @fastify/cors registers withorigin: false. The APK uses fetch/axios from WebView (not CapacitorHttp plugin), so CORS applies. Without the header, the WebView discards responses. The app is either broken or relies on a manual Render dashboard config not in the repo.Impact
Proposed Fix
trustProxy: truetotrustProxy: 1(single proxy hop)CORS_ALLOWED_ORIGINS=https://localhost,capacitor://localhost,http://localhostas defaultFiles to modify
micopay/backend/src/index.ts(line 34)micopay/backend/src/config.ts(lines 35-44)Acceptance Criteria