security: P1/P2 hardening — rate limiting, CORS, Redis auth, network isolation

- Add Redis-based sliding window rate limiting on login, register, forgot-password, reset-password
- Fix user enumeration: register returns generic 200 for both new and existing emails
- Add Redis authentication (requirepass) and password in .env
- Docker network isolation: postgres/redis on internal-only network
- Whitelist Stripe redirect origins (prevent open redirect)
- Add 10MB request size limit on trace ingestion
- Limit API keys to 10 per user
- Add CORS headers via middleware (whitelist agentlens.vectry.tech + localhost)
- Reduce JWT max age from 30 days to 7 days
This commit is contained in:
Vectry
2026-02-10 17:03:48 +00:00
parent e9cd11735c
commit cccb3123ed
17 changed files with 315 additions and 34 deletions

View File

@@ -7,7 +7,7 @@ services:
- "4200:3000"
environment:
- NODE_ENV=production
- REDIS_URL=redis://redis:6379
- REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379
- DATABASE_URL=postgresql://${POSTGRES_USER:-agentlens}:${POSTGRES_PASSWORD:-agentlens}@postgres:5432/${POSTGRES_DB:-agentlens}
- AUTH_SECRET=${AUTH_SECRET}
- AUTH_TRUST_HOST=true
@@ -18,11 +18,14 @@ services:
- EMAIL_PASSWORD=${EMAIL_PASSWORD:-}
depends_on:
redis:
condition: service_started
condition: service_healthy
postgres:
condition: service_healthy
migrate:
condition: service_completed_successfully
networks:
- frontend
- backend
healthcheck:
test: ["CMD", "wget", "--spider", "--quiet", "http://127.0.0.1:3000/api/health"]
interval: 30s
@@ -50,6 +53,8 @@ services:
- POSTGRES_DB=${POSTGRES_DB:-agentlens}
volumes:
- agentlens_postgres_data:/var/lib/postgresql/data
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U agentlens"]
interval: 10s
@@ -76,15 +81,19 @@ services:
depends_on:
postgres:
condition: service_healthy
networks:
- backend
restart: "no"
redis:
image: redis:7-alpine
command: redis-server --maxmemory 64mb --maxmemory-policy allkeys-lru
command: redis-server --maxmemory 64mb --maxmemory-policy allkeys-lru --requirepass ${REDIS_PASSWORD}
volumes:
- agentlens_redis_data:/data
networks:
- backend
healthcheck:
test: ["CMD", "redis-cli", "ping"]
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 3
@@ -99,6 +108,11 @@ services:
max-file: "3"
restart: always
networks:
frontend:
backend:
internal: true
volumes:
agentlens_postgres_data:
agentlens_redis_data: