Tier 1 hardening: trustProxy + per-IP rate limit + anonymity flag
- Fastify public app now passes `trustProxy: true` so request.ip resolves to the real client IP from X-Forwarded-For when behind Cloud Run / a load balancer. Without this the per-IP rate limit was either useless or collapsed all users into one shared LB IP. - The `anonymity_enabled` config row + JS default + migration seed now default to `false`. The flag is dead code (no business logic ever consumed it) and the actual rule is simpler than the toggle implied: mitras always see the customer's chosen call_name; only phone+email are private. The whole feature is queued for rip-out as a separate cleanup pass. The per-IP OTP rate limit (10/hr) was also effectively disabled by upserting `app_config.otp_max_per_ip_per_hour = 1000000` — a runtime config change, not a code change. Per-phone (3/hr) + Fazpass cost remains the real abuse gate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ import { errorHandler } from './plugins/error-handler.js'
|
|||||||
import { registerWebSocketPlugin, registerWebSocketRoute } from './plugins/websocket.js'
|
import { registerWebSocketPlugin, registerWebSocketRoute } from './plugins/websocket.js'
|
||||||
|
|
||||||
export const buildPublicApp = async () => {
|
export const buildPublicApp = async () => {
|
||||||
const app = Fastify({ logger: true })
|
const app = Fastify({ logger: true, trustProxy: true })
|
||||||
|
|
||||||
await app.register(cors, { origin: true })
|
await app.register(cors, { origin: true })
|
||||||
await app.register(sensible)
|
await app.register(sensible)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ const migrate = async () => {
|
|||||||
|
|
||||||
await sql`
|
await sql`
|
||||||
INSERT INTO app_config (key, value)
|
INSERT INTO app_config (key, value)
|
||||||
VALUES ('anonymity', '{"enabled": true}')
|
VALUES ('anonymity', '{"enabled": false}')
|
||||||
ON CONFLICT (key) DO NOTHING
|
ON CONFLICT (key) DO NOTHING
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const sql = getDb()
|
|||||||
|
|
||||||
export const getAnonymityConfig = async () => {
|
export const getAnonymityConfig = async () => {
|
||||||
const [row] = await sql`SELECT value FROM app_config WHERE key = 'anonymity'`
|
const [row] = await sql`SELECT value FROM app_config WHERE key = 'anonymity'`
|
||||||
return { anonymity_enabled: row?.value?.enabled ?? true }
|
return { anonymity_enabled: row?.value?.enabled ?? false }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setAnonymityConfig = async (enabled) => {
|
export const setAnonymityConfig = async (enabled) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user