Private
Public Access
1
0
Files
Purrse/docker-compose.yml
T
Catherine Renelle 2f389ab8e9 Security hardening: fix IDOR vulnerabilities, add rate limiting, SSRF protection, and encryption upgrades
- Fix ReconciliationController and BankSync LinkAccount/UpdateLinkedAccount IDOR (verify account ownership)
- Add ASP.NET Core rate limiting: strict on auth endpoints, global on all API routes
- Harden SSRF validation on Ollama URL (IPv6-mapped bypass, link-local, 0.0.0.0 blocking)
- Upgrade encryption from AES-CBC to AES-GCM with HKDF key derivation (backward-compatible decrypt)
- Add startup validation that rejects default JWT/encryption keys in Production
- Add security headers (X-Frame-Options, CSP, HSTS, Cache-Control, nosniff) to API and nginx
- Mask account numbers in API responses (show last 4 digits only)
- Add password strength validation (min 8 chars) and BCrypt work factor 12
- Hash refresh tokens (SHA-256) before database storage
- Set JWT ClockSkew to zero for immediate expiry enforcement
- Add file upload size limit (10 MB) and filename sanitization
- Cap transaction search PageSize to 200
- Fix FileWatcherService cross-user account matching in multi-user deployments
- Sanitize console.error calls to prevent token leakage in browser logs
- Parameterize raw SQL in SimpleFinConnectionMigration
- Make AuthService.GenerateAuthResponse fully async

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:53:20 -05:00

63 lines
1.6 KiB
YAML

services:
db:
image: postgres:17-alpine
container_name: purrse-db
environment:
POSTGRES_DB: purrse
POSTGRES_USER: purrse
POSTGRES_PASSWORD: ${DB_PASSWORD:-purrse_dev}
ports:
- "5433:5432"
volumes:
- purrse-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U purrse"]
interval: 5s
timeout: 5s
retries: 5
api:
build:
context: .
dockerfile: src/Purrse.Api/Dockerfile
container_name: purrse-api
environment:
- ConnectionStrings__DefaultConnection=Host=db;Port=5432;Database=purrse;Username=purrse;Password=${DB_PASSWORD:-purrse_dev};Ssl Mode=Prefer;Trust Server Certificate=true
- Jwt__Key=${JWT_KEY:-PurrseDefaultSecretKey_ChangeInProduction_AtLeast32Chars!}
- Jwt__Issuer=Purrse
- Jwt__Audience=Purrse
- Cors__Origins__0=http://localhost:9080
- Plugins__Path=/app/plugins
- Imports__WatchPath=/app/imports
ports:
- "5000:8080"
volumes:
- purrse-plugins:/app/plugins
- purrse-imports:/app/imports
depends_on:
db:
condition: service_healthy
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: purrse-frontend
ports:
- "9080:80"
depends_on:
- api
docker-cleanup:
image: docker:cli
container_name: purrse-docker-cleanup
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
entrypoint: ["/bin/sh", "-c", "while true; do sleep 86400; docker image prune -f; done"]
volumes:
purrse-db-data:
purrse-plugins:
purrse-imports: