fix(securitate): hardening prod — headere, body-cap, non-root, backup
Findings security-review P1/P2 (2026-07-03): - headere de securitate pe toate raspunsurile (nosniff, X-Frame-Options, Referrer-Policy, HSTS doar pe HTTPS) + teste - body-cap global 10MB ca middleware ASGI pur (413 inainte de parserul multipart/JSON; verificarea per-endpoint ramane strat 2) - imagine Docker non-root (uid 10001), port 8010 aliniat, loguri pe volumul /data - fail-fast la boot cu rar_env=prod fara AUTOPASS_REQUIRE_API_KEY sau AUTOPASS_SESSION_SECRET - compose: env-uri critice obligatorii (:?) ca api/worker sa nu diverga tacit; FORWARDED_ALLOW_IPS ca rate-limit-ul sa vada IP-ul real dupa Traefik - signup fara PII in stdout: log_event in loc de print cu email (idem notify degradat) - ratelimit: sterge cheile fara timestamp-uri valide (crestere monotona a memoriei pe IP-uri reale) - backup criptat SQLite (backup online API, gpg AES256) + verificare restore + docs/backup.md Suita completa verde: 1557 passed, 1 skipped (live). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
26
Dockerfile
26
Dockerfile
@@ -11,9 +11,19 @@ ENV PYTHONUNBUFFERED=1 \
|
||||
WORKDIR /app
|
||||
|
||||
# tzdata = necesar pentru ca 'localtime' din SQLite sa rezolve Europe/Bucharest.
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends tzdata \
|
||||
# gnupg = criptare backup SQLite (tools/backup_db.sh, T2/P0-4) — NU e inclus implicit
|
||||
# in imaginea slim (doar gzip e pachet esential Debian). rclone NU e instalat aici
|
||||
# intentionat: upload-ul remote e optional (AUTOPASS_BACKUP_RCLONE_REMOTE) si scriptul
|
||||
# sare peste el explicit daca binarul lipseste.
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends tzdata gnupg \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# User neprivilegiat (uid/gid stabil): orice RCE viitor are raza de explozie
|
||||
# limitata, nu root in container. HOME e necesar explicit — fastembed descarca
|
||||
# modelul (~230MB) in $HOME la prima folosire (AUTOPASS_EMBEDDINGS_ENABLED=true).
|
||||
RUN groupadd -g 10001 app && useradd -u 10001 -g app -d /home/app -m app
|
||||
ENV HOME=/home/app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
@@ -22,9 +32,19 @@ COPY tools ./tools
|
||||
|
||||
# Date persistente (SQLite WAL) pe volum montat.
|
||||
ENV AUTOPASS_DB_PATH=/data/autopass.db
|
||||
# Log text rotativ (app/config.py:log_dir, RotatingFileHandler) pe acelasi volum
|
||||
# persistent, NU in /app/.run — altfel non-root n-are voie sa scrie in /app.
|
||||
ENV AUTOPASS_LOG_DIR=/data/logs
|
||||
|
||||
# chown INAINTE de VOLUME — schimbarile de proprietar dupa directiva VOLUME se
|
||||
# pierd la build. Migrare one-off pentru un volum EXISTENT deja detinut de root:
|
||||
# docker compose run --rm --user root api chown -R app:app /data
|
||||
RUN mkdir -p /data && chown app:app /data
|
||||
VOLUME ["/data"]
|
||||
|
||||
EXPOSE 8000
|
||||
USER app
|
||||
|
||||
EXPOSE 8010
|
||||
|
||||
# Default = API. Worker-ul suprascrie command in compose.
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8010"]
|
||||
|
||||
Reference in New Issue
Block a user