Audit de sécurité LLM #110
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
🔒 Correctifs de sécurité appliqués (audit accès SQLite / prise de contrôle serveur)
Suite à l'audit, application des correctifs critiques et moyen. Aucun chemin de prise de contrôle serveur (RCE) n'a été trouvé (pas de
eval/exec/subprocess/pickle, DuckDB enread_only, requêtes API à colonnes whitelistées + binding?, sandbox systemd solide). Le risque réel portait sur la lecture/écriture de la base SQLite utilisateurs.🔴 Critique — Contournement d'autorisation du panneau admin
src/pages/admin/liste.py— le callback_update_table(endpoint serveur global/_dash-update-component) ne revérifiait pasis_admin(): la garde n'existait que danslayout(). Un non-admin — voire un anonyme (le chemin lecture ne touche pascurrent_user) — pouvait :users,subscriptions,subscriber_state(emails, siret, handles Frisbii, statuts…) ;UPDATEparamétré), y compris se hisser admin en changeant son email versADMIN_EMAIL.Aggravé par l'exemption CSRF des routes
/_dash(src/app.py) et leAccess-Control-Allow-Origin *de nginx (exfiltration cross-origin en drive-by).Fix : garde
if not is_admin(): raise PreventUpdateen tête du callback (couvre lecture ET écriture).Test de non-régression :
tests/admin/test_callback_guard.py(invoque le callback directement en non-admin) — ✅ 3 tests. Les tests E2E existants restent verts (l'admin n'est pas affecté).🔴 Critique (aggravant) — CORS ouvert dans nginx
colibre_ynh/conf/nginx.conf— suppression duadd_header Access-Control-Allow-Origin *. L'app est à base de sessions (cookies) et expose des callbacks exemptés de CSRF ; le front Dash est same-origin et n'en a pas besoin. Unlocation /api/dédié (jetons Bearer, origine explicite) reste possible si besoin plus tard.🟠 Moyen —
SECRET_KEYnon généré + template.envYNH obsolèteLe template ne définissait aucun secret (dont
SECRET_KEY, obligatoire au démarrage). Risque : secret ajouté à la main, potentiellement faible/prévisible → forge de cookie de session → usurpation de compte.Fix (
colibre_ynh/) :scripts/install: génération d'unsecret_keyaléatoire (ynh_string_random --length=48) persisté comme setting ;scripts/upgrade: génération d'un défaut si absent (installs existantes) ;conf/.env: template complété (aligné sur.template.env), avecSECRET_KEY=__SECRET_KEY__et secrets externes en placeholders vides à renseigner.🟢 Bonus de durcissement (inclus dans la complétion du template)
USERS_DB_PATHetDUCKDB_PATHdéplacés dans__DATA_DIR__: hors de l'arborescence servie et persistant — sans ça,users.sqliteen défaut relatif (CWD =install_dir) était effacée à chaque upgrade parynh_setup_source --full_replace. ⚠️ À vérifier sur l'instance en production : que la base actuelle pointe bien versdata_dir.Reste à traiter (faible, non bloquant) : liaison OAuth sur email non vérifié (
auth/routes.py:43),restoreréférençant des configs fail2ban jamais créées, source d'install sur branchedevmouvante plutôt qu'un tag.Correctifs non commités (édités dans l'arbre de travail des deux dépôts).