Files
rar-autopass/Dockerfile
Claude Agent 63b6cbc01d 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>
2026-07-06 12:46:49 +00:00

51 lines
2.0 KiB
Docker

# Gateway RAR AUTOPASS — imagine unica (API + worker ruleaza ca servicii separate
# din acelasi image, vezi docker-compose.yml).
FROM python:3.12-slim
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
# Fus orar RO: SQLite 'localtime' (bucketare contoare azi/luna, E7) depinde de TZ.
# tzdata ofera baza de fusuri; TZ alege Europe/Bucharest (DST-aware, UTC+2/+3).
TZ=Europe/Bucharest
WORKDIR /app
# tzdata = necesar pentru ca 'localtime' din SQLite sa rezolve Europe/Bucharest.
# 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
COPY app ./app
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"]
USER app
EXPOSE 8010
# Default = API. Worker-ul suprascrie command in compose.
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8010"]