Files
aurum/docker-compose.yml
technosexual b045d378f0 fix(security): stop granting every origin credentialed access to the API (#5)
`AURUM_CORS_ORIGINS` defaults to `*`, and the middleware was configured with
`allow_credentials=True`. Starlette does not answer that combination with a
literal `*` — it echoes back whatever `Origin` the caller sent and adds
`Access-Control-Allow-Credentials: true`, so any page open in the same
browser can call the instance, with the user's Basic Auth attached, and read
the response:

    GET /api/accounts   Origin: https://evil.example
    -> Access-Control-Allow-Origin: https://evil.example
       Access-Control-Allow-Credentials: true

That undercuts the README's advice that leaving Basic Auth off is fine while
the instance is only reachable from localhost: reachable-from-localhost
includes every website the user visits.

Nothing in the shipped setup is cross-origin. Compose serves the UI and the
API from the same nginx, and the Vite dev server proxies `/api`
(frontend/vite.config.ts), so neither deployment nor development needs CORS
at all. The default is therefore empty — no cross-origin access — and the
middleware is only installed when origins are configured deliberately.

An explicit `*` is still honoured for a genuinely public read-only setup, but
never together with credentials, which is what the spec intends `*` to mean
anyway.
2026-08-30 18:11:09 +03:00

49 lines
1.5 KiB
YAML

services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${AURUM_POSTGRES_USER:-aurum}
POSTGRES_PASSWORD: ${AURUM_POSTGRES_PASSWORD:-aurum}
POSTGRES_DB: ${AURUM_POSTGRES_DB:-aurum}
volumes:
- aurum_pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${AURUM_POSTGRES_USER:-aurum}"]
interval: 5s
timeout: 5s
retries: 10
backend:
build: ./backend
restart: unless-stopped
environment:
AURUM_POSTGRES_USER: ${AURUM_POSTGRES_USER:-aurum}
AURUM_POSTGRES_PASSWORD: ${AURUM_POSTGRES_PASSWORD:-aurum}
AURUM_POSTGRES_DB: ${AURUM_POSTGRES_DB:-aurum}
AURUM_POSTGRES_HOST: db
AURUM_POSTGRES_PORT: 5432
AURUM_CORS_ORIGINS: ${AURUM_CORS_ORIGINS:-}
AURUM_DEFAULT_CURRENCY: ${AURUM_DEFAULT_CURRENCY:-USD}
# Free CoinGecko Demo key (coingecko.com/en/api/pricing) — the Crypto
# tab's price sync 400s with a clear message until this is set.
AURUM_COINGECKO_API_KEY: ${AURUM_COINGECKO_API_KEY:-}
depends_on:
db:
condition: service_healthy
web:
build: ./frontend
restart: unless-stopped
ports:
- "${AURUM_WEB_PORT:-3000}:80"
environment:
# Both unset = no login screen at all. See frontend/docker-entrypoint.d/20-basic-auth.sh.
AURUM_BASIC_AUTH_USER: ${AURUM_BASIC_AUTH_USER:-}
AURUM_BASIC_AUTH_PASSWORD: ${AURUM_BASIC_AUTH_PASSWORD:-}
depends_on:
- backend
volumes:
aurum_pgdata: