2f389ab8e9
- 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>
63 lines
1.6 KiB
YAML
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:
|