AUDIT COMPLET - Stack 33800
Date : 15/02/2026
Status : IMPLEMENTEE
Scope : 5 projets (ai-orchestrator, connectors-api, ulias-org, ulias-org-web, dashboard-33800)
Mode : LECTURE SEULE - aucun fichier modifie
TABLE DES MATIERES
- Resume executif
- ai-orchestrator
- connectors-api
- ulias-org
- ulias-org-web
- dashboard-33800
- Problemes transverses
- Plan d'action prioritaire
RESUME EXECUTIF
| Projet |
CRITIQUE |
HAUTE |
MOYENNE |
BASSE |
Total |
| ai-orchestrator |
1 |
12 |
15 |
20+ |
~48 |
| connectors-api |
5 |
10 |
10 |
9 |
34 |
| ulias-org |
1 |
7 |
13 |
14 |
35 |
| ulias-org-web |
1 |
4 |
9 |
13 |
27 |
| dashboard-33800 |
- |
- |
- |
- |
(partiel) |
| TOTAL |
8 |
33 |
47 |
56+ |
~144 |
Top 10 des problemes les plus graves
| # |
Projet |
ID |
Description |
| 1 |
connectors-api |
S-01 |
JWT signature non verifiee - usurpation d'identite |
| 2 |
connectors-api |
S-03 |
/api/fetch accepte requetes non authentifiees |
| 3 |
connectors-api |
B-01 |
wireguard.ts utilise API Supabase inexistante - TOUT VPN crashe |
| 4 |
ai-orchestrator |
S-01 |
Credentials (Redis/PG passwords) en dur dans le code source |
| 5 |
ai-orchestrator |
S-03 |
Pas d'auth (service interne, risque modere) |
| 6 |
connectors-api |
S-02 |
POST /api/connectors/:id/token sans auth |
| 7 |
connectors-api |
S-06 |
Cle chiffrement par defaut en production |
| 8 |
ulias-org |
1.1 |
Briefing processAnswer logique inversee |
| 9 |
ulias-org-web |
P22 |
Sidebar polling 500ms infini apres toggle |
| 10 |
connectors-api |
S-09 |
OAuth state non signe (CSRF) |
1. AI-ORCHESTRATOR
Chemin : /stock_8to/33800-stack/projects/ai-orchestrator/
Fichier principal : app/main.py (4675 lignes)
Runtime : Python / FastAPI
1.1 SECURITE
S-01 [CRITIQUE] Credentials en dur dans le code source
- Fichier :
app/main.py, lignes 35-40
- Mots de passe Redis et PostgreSQL hardcodes en valeur par defaut. Fichier versionne dans Git.
- Fix : Supprimer les valeurs par defaut. Exiger les env vars au startup.
S-03 [MOYENNE] Pas d'authentification (service interne)
- Fichier :
app/main.py, tous les endpoints
- Pas de middleware d'auth. Mais ai-orchestrator est un service interne (reseau local, nginx
private: true), pas expose sur internet. Seuls les services internes (connectors-api, ulias-org) y accedent.
- Fix : Bonne pratique a terme (API key interne), mais pas un risque immediat.
S-02 [MOYENNE] CORS allow_origins=["*"] avec allow_credentials=True
- Lignes 177-182. Devrait etre restreint aux domaines reels.
S-04 [HAUTE] Injection de commandes via SSH
- Ligne 814.
run_ssh_command ne protege pas contre les injections shell ($(), backticks, ;, &&).
- Fix : Utiliser
shlex.quote().
S-06 [HAUTE] Upload de fichiers sans validation
- Lignes 4511-4537. Pas de limite de taille, pas de verification de type MIME.
1.2 BUGS LOGIQUES
B-01 [HAUTE] Race condition sur active_tools
- Dict global mutable accede sans lock par le worker, les endpoints API, et les jobs concurrents.
- Fix :
asyncio.Lock() sur les modifications.
B-03 [HAUTE] Cloud jobs (Anthropic) sans limite de concurrence
- Ligne 4268-4271.
asyncio.create_task() sans semaphore. Dizaines d'appels Anthropic possibles en parallele sans controle.
- Fix : Ajouter un semaphore pour limiter les jobs cloud.
B-05 [HAUTE] Requeue infini possible
- Lignes 3952-3994. Jobs requeuees indefiniment sans compteur de retry.
- Fix : Incrementer retry_count, fail apres N retries.
B-13 [HAUTE] vram_used parsing fragile
- Lignes 4027, 4206-4207.
int(gpu.vram_used.replace(" Mo", "")) crashe si "N/A".
- Fix : Try/except ou check "N/A" avant parsing.
1.3 VRAM MANAGEMENT
V-01 [HAUTE] Estimation VRAM Ollama approximative
- Lignes 741-764. Pattern matching sur le nom du modele.
num_ctx non pris en compte.
- Fix : Interroger Ollama
/api/show pour la taille reelle.
V-02 [HAUTE] gpu_vram_committed surestimation
- Lignes 4136-4144. Prend le max des estimations au lieu de la somme (quand 2 modeles charges).
- Fix : Sommer la VRAM des modeles uniques charges.
V-03 [HAUTE] keep_alive=-1 sur GPU1 = modele charge indefiniment
- Ligne 2520. Sur la 2070S (8 Go), le modele reste en VRAM indefiniment.
- Fix : Reduire keep_alive sur GPU1 a 5m-10m.
V-05 [HAUTE] Pas de mecanisme de preemption/unload
- Si Ollama a charge un modele 20 GB et qu'un job ComfyUI arrive, l'orchestrateur attend indefiniment.
- Fix : Envoyer un unload (keep_alive: 0) avant dispatch d'un exclusive tool.
1.4 GESTION D'ERREURS
E-02 [HAUTE] Redis/PG failure non gere en cours de vie
- Pas de reconnexion automatique si Redis/PG deviennent injoignables.
E-03 [HAUTE] Health endpoint fragile
- Lignes 1060-1062.
/health fait un appel Redis. Si Redis est down, le container restart en boucle.
- Fix : Try/except, retourner 503 "degraded".
E-05 [HAUTE] Ollama generate sans num_ctx
- Lignes 2653-2663. Type "generate" n'envoie pas num_ctx → OOM possible.
- Fix : Ajouter
num_ctx: 8192 par defaut.
1.5 HARDCODE
H-04 [MOYENNE] Modele par defaut obsolete dans schemas
"default": "mistral:latest" dans les schemas, "llama3.1:8b" dans le code, qwen3:8b en realite.
H-06 [MOYENNE] costs_summary year/month hardcodes
- Ligne 4595.
year: int = 2026, month: int = 2 → obsolete le mois suivant.
- Fix :
datetime.now().year / .month.
1.6 QUEUE / CODE
- Q-01 [MOYENNE] : Requeue met le job en fin de queue au lieu de le remettre en tete.
- Q-03 [MOYENNE] : Job cancelled mais toujours en queue Redis (race condition).
- C-04 [MOYENNE] : SadTalker chemins incoherents (start_cmd vs CLI).
- C-06 [BASSE] : Pydantic
.dict() deprecated → .model_dump().
- E-01 [MOYENNE] : Bare
except: partout (catch SystemExit, KeyboardInterrupt).
2. CONNECTORS-API
Chemin : /stock_8to/33800-stack/projects/connectors-api/
Runtime : Bun / Elysia (TypeScript)
Rapport detaille : ~/propositions/15-02-2026-18-00-audit-connectors-api.md
2.1 SECURITE
S-01 [CRITIQUE] JWT signature non verifiee
src/middleware/jwt.ts ligne 29-51
- Le payload JWT est decode (base64) mais la signature HMAC n'est JAMAIS verifiee.
JWT_SECRET lu mais jamais utilise.
- Impact : Usurpation d'identite complete.
S-02 [CRITIQUE] POST /api/connectors/:id/token sans auth
src/index.ts ligne 1767-1787
- Endpoint admin sans aucun controle d'acces.
S-03 [CRITIQUE] /api/fetch accepte requetes non authentifiees
src/index.ts lignes 201-204
getAuthFromRequest() retourne null → le handler continue avec userId = null.
S-06 [HAUTE] Cle de chiffrement par defaut
src/services/ssh.ts ligne 105 : 'default-key-change-in-production-32!'
- Tous les credentials SSH/VPN chiffres avec une cle dans le code source.
S-07 [HAUTE] Salt statique 'salt' pour scrypt
- 6 occurrences dans 3 fichiers. Reduit la securite de scrypt.
S-08 [HAUTE] new Function() execute du code utilisateur sans sandbox
src/services/actions.ts ligne 853. Acces a fetch() et au contexte serveur.
S-09 [HAUTE] OAuth state non signe (CSRF)
- Le state OAuth contient
user_id en base64 sans HMAC.
2.2 BUGS
B-01 [CRITIQUE] wireguard.ts utilise API Supabase inexistante
src/services/wireguard.ts, 12+ occurrences
- Utilise
supabase.from().select().eq().single() mais le wrapper n'expose pas cette API. TOUTES les fonctions VPN crashent au runtime.
B-02 [HAUTE] Ternaire scope check no-op
src/index.ts ligne 207 : SCOPES.FETCH : SCOPES.FETCH (les deux branches identiques).
S-04 [HAUTE] Injection commande SSH dans setupAutoKey
src/services/ssh.ts ligne 997. Cle publique interpolee dans un shell.
S-05 [HAUTE] Variable escapedContent inutilisee dans heredoc
src/services/ssh.ts lignes 1067-1068. Contenu brut utilise au lieu de l'echappe.
2.3 HARDCODE
- H-01 [MOYENNE] : IP:port pour ai-orchestrator (
src/services/ai.ts:159)
- H-02 [MOYENNE] : IP:port pour notif-logger (
src/services/notify.ts:5)
- H-05 [BASSE] : Version incoherente : 2.3.2, 2.4.0, 2.5.0 dans 3 endroits
2.4 CODE
- B-04 [MOYENNE] : audit.log avec snake_case au lieu de camelCase
- B-05 [MOYENNE] : evaluateCondition utilise egalite lache
==
- B-07 [MOYENNE] : Dead code query/params → filtre include_public ne fonctionne pas
- D-03 [BASSE] : Duplication encrypt/decrypt dans 3 fichiers
3. ULIAS-ORG
Chemin : /stock_8to/33800-stack/projects/ulias-org/
Runtime : Bun / Elysia (TypeScript)
3.1 BUGS
1.1 [CRITIQUE] Briefing processAnswer logique inversee
packages/server/src/briefing/index.ts ligne 205
- La condition qui teste si l'utilisateur peut skip une question est inversee.
- Les questions required ne peuvent PAS etre skipees mais les non-required sont skipees quand elles ne devraient pas l'etre.
3.2 SECURITE / AUTH
11.7 [HAUTE] GITLAB_TOKEN en clair dans conf.prod.gouroubleu.yml
- Ligne 10. Token GitLab complet visible dans le repo git.
10.1 [HAUTE] Endpoints retournent HTTP 200 pour les erreurs
{ error: 'Not authenticated' } avec HTTP 200. Le client ne distingue pas succes/erreur.
- Fix : Utiliser
set.status = 401 / set.status = 404.
10.2 [MOYENNE] /api/agents expose les prompts sans auth
- Les prompts contiennent des IPs, architecture reseau, noms de machines.
10.5 [MOYENNE] Endpoints /internal/* non proteges
/internal/job-callback/:callbackId et /internal/pending-jobs sans token.
- Un attaquant peut poster des faux callbacks LLM.
7.3 [MOYENNE] API key en clair dans ceo_profile
- Table
ceo_profile.preferences.connector_api_key lisible via Supabase.
3.3 WEBSOCKET
5.1 [HAUTE] WS deconnexion non geree dans le handler
ws.send() sans verifier que le WS est encore ouvert. Les event callbacks continuent apres fermeture.
- Fix : Wrapper
ws.send(), propager la fermeture via AbortController.
9.1 [HAUTE] WS error handler renvoie sur WS potentiellement ferme
- Le catch tente
ws.send() sur un WS ferme → nouvelle exception non catchee.
5.2 [MOYENNE] session.ws non nettoyee a la deconnexion
session.ws pointe vers un WS ferme. Les REST endpoints qui tentent d'envoyer via session.ws crashent.
3.4 HARDCODE
2.1 [HAUTE] CALLBACK_BASE_URL hardcode avec IP:port
packages/server/src/tools/client.ts ligne 112 : 'http://192.168.1.12:5515'
- Variable
CALLBACK_BASE_URL non definie dans l'env.
2.2 [HAUTE] CONNECTORS_API_URL fallback mauvais port
packages/server/src/index.ts ligne 16 : port 5400 au lieu de 5403.
2.4 [MOYENNE] CLI default port 5510 (claude-memory) au lieu de 5515 (ulias-org)
packages/cli/bin/ulias.ts ligne 13.
3.5 LLM ROUTING
3.1 [HAUTE] Timeout routing LLM 180s au lieu de 90s
packages/server/src/agents/interpreter.ts ligne 231. L'utilisateur attend 3 minutes avant fallback.
3.4 [MOYENNE] num_ctx pas envoye pour routing/suggestions/title
- Le
llmChat ajoute num_ctx: 16384 par defaut (mitige) mais pas explicite.
3.6 CODE
- 1.2 [MOYENNE] :
editFile ne remplace que la premiere occurrence (String.replace)
- 1.3 [MOYENNE] : message_count race condition (GET + increment + UPDATE non atomique)
- 6.1 [MOYENNE] : Scheduler absent du code mais reference dans les configs
- 11.4 [MOYENNE] : searchConversations vulnerable injection PostgREST
- 11.5 [BASSE] : Dockerfile copie
bun.lockb* mais le fichier est bun.lock
- 11.6 [BASSE] : Test registry attend 7 equipes, il y en a 8
4. ULIAS-ORG-WEB
Chemin : /stock_8to/33800-stack/projects/ulias-org-web/
Runtime : Qwik + Express (TypeScript)
4.1 BUGS
P22 [CRITIQUE] Sidebar polling 500ms infini
ConversationSidebar.tsx lignes 151-156
setInterval 500ms ne s'arrete jamais apres un toggle de showArchived. Apres un clic, loadConversations() est appele 2x/seconde indefiniment.
- Fix : Supprimer l'interval, garder seulement le fetch dans onClick.
P23 [HAUTE] Double fetch au toggle (lie a P22)
- Le handler onClick fait un fetch ET l'interval detecte le changement et fait un second fetch.
4.2 UX
P18 [HAUTE] Suppression conversation sans confirmation
ConversationSidebar.tsx lignes 211-225. Un clic accidentel supprime irreversiblement.
- Fix : Ajouter
confirm().
P29 [HAUTE] Navbar 8 tabs deborde sur mobile
layout.tsx lignes 225-269. Pas de overflow-x-auto ni menu hamburger.
P19 [MOYENNE] Suppression objectif sans confirmation
history/index.tsx lignes 85-95.
P25 [MOYENNE] window.location.href au lieu de SPA navigation
history/index.tsx ligne 82. Rechargement complet au lieu de useNavigate().
4.3 WEBSOCKET
P13 [HAUTE] WS reconnexion limitee a 5 tentatives sans retry
ws-manager.ts lignes 6-7, 114-125. Apres 5 echecs, le WS reste deconnecte indefiniment. Pas de bouton "Reconnecter".
P14 [MOYENNE] Pas de heartbeat/ping WebSocket
- Connexion TCP perdue silencieusement → WS affiche "Connecte" alors qu'il est mort.
4.4 RENDU
P08 [MOYENNE] Markdown renderer casse les URLs avec & ou "
markdown.ts lignes 7-13. escapeHtml avant parsing des liens → double echappement &.
P10 [MOYENNE] Types incomplets dans types.ts vs donnees reelles
EventCard.tsx lignes 67-138. Le backend envoie plus de donnees que les types ne declarent.
P32 [MOYENNE] URLs javascript: non filtrees dans le Markdown
markdown.ts ligne 46. Les liens Markdown [text](javascript:...) ne sont pas bloques.
4.5 HARDCODE
P04 [MOYENNE] URL API_URL hardcodee dans 14 fichiers
- Pattern
import.meta.env.PUBLIC_API_URL || 'https://ulias-org.33800.nowhere84.com' repete partout.
- Fix : Centraliser dans
~/lib/config.ts.
4.6 CODE
- P06 [BASSE] : manifest.json reference mais inexistant
- P15 [BASSE] : Pas de plugin@auth.ts (flash cosmetic, pas de fuite de donnees)
- P20/P21 [BASSE] : DaisyUI v4 class
loading obsolete sur les boutons
- P34/P35 [BASSE] : Variables
progress et isProgressEvent inutilisees
- P37 [BASSE] : DocumentHead manquant sur 6 routes
Points positifs
- Pattern WebSocket receive-only correctement implemente (conforme Qwik)
escapeHtml avant rendu Markdown (securise)
- Pas de
.sort() dans le render (le bug connu est evite)
- Cleanup correct dans tous les
useVisibleTask$
5. DASHBOARD-33800
Chemin : /stock_8to/33800-stack/monitoring/
Type : Scripts bash generant du HTML statique
L'audit du dashboard a explore les fichiers mais n'a pas produit de rapport structure complet. Observations notables :
- generate.sh (4900+ lignes) : Fichier monolithique tres long
- Pages sensibles deployees via SCP direct sur nginx (alerts, doc, secrets, endpoints, montages, services) au lieu du mecanisme git/deploy_page. Coherent avec le workflow "pas de CI/CD pour dashboard"
- CSS variable
--orange utilisee dans ai-jobs.sh mais avec fallback inline (var(--orange, #f97316)) → pas de bug
- Modeles Ollama dans le formulaire "New Job" :
qwen2.5:7b et llama3.1:8b hardcodes alors que le modele par defaut est qwen3:8b
- gitlab-jobs.html : reference dans la nav mais aucun module ne le genere
6. PROBLEMES TRANSVERSES
6.1 Credentials exposes dans le code source
| Projet |
Fichier |
Credential |
| ai-orchestrator |
main.py:35-40 |
Redis/PG passwords |
| ulias-org |
conf.prod.gouroubleu.yml:10 |
GITLAB_TOKEN |
| connectors-api |
ssh.ts:105 |
Cle chiffrement par defaut |
6.2 IPs hardcodees (violation regle "jamais d'IP:port dans le code")
| Projet |
Fichier |
IP:port |
| ai-orchestrator |
main.py:185 |
WIN11_HOST 192.168.1.30 |
| ulias-org |
client.ts:112 |
CALLBACK_BASE 192.168.1.12:5515 |
| ulias-org |
index.ts:16 |
CONNECTORS_API 192.168.1.12:5400 (mauvais port!) |
| ulias-org |
client.ts:637 |
Supabase 192.168.1.12:8200 |
| connectors-api |
ai.ts:159 |
ai-orchestrator 192.168.1.12:5501 |
| connectors-api |
notify.ts:5 |
notif-logger 192.168.1.12:5300 |
| connectors-api |
userStorage.ts:501 |
Supabase 192.168.1.12:8000 |
6.3 Absence d'authentification
| Projet |
Endpoint |
Risque |
| ai-orchestrator |
TOUS |
Critique - 0 auth |
| connectors-api |
/api/fetch |
Critique - auth bypassable |
| connectors-api |
POST /api/connectors/:id/token |
Critique - admin sans auth |
| ulias-org |
/api/agents |
Expose les prompts systeme |
| ulias-org |
/internal/* |
Callbacks falsifiables |
6.4 WebSocket - problemes communs backend + frontend
- Backend (ulias-org) :
ws.send() sans verifier l'etat du WS, pas de cleanup session
- Frontend (ulias-org-web) : Reconnexion limitee a 5 tentatives, pas de heartbeat
7. PLAN D'ACTION PRIORITAIRE
Phase 1 : Corrections critiques (immediat)
- connectors-api S-01 : Implementer verification signature JWT (HMAC-SHA256)
- connectors-api S-03 : Exiger auth sur /api/fetch
- connectors-api S-02 : Ajouter auth sur POST /api/connectors/:id/token
- connectors-api B-01 : Reecrire wireguard.ts avec le bon wrapper Supabase
- connectors-api S-06 : Erreur fatale si SSH_ENCRYPTION_KEY absent
- ai-orchestrator S-01 : Supprimer credentials par defaut du code
- ai-orchestrator S-03 : Ajouter middleware API key
- ulias-org-web P22 : Supprimer le setInterval 500ms de la sidebar
- ulias-org 1.1 : Corriger la logique inversee du briefing processAnswer
Phase 2 : Securite haute (< 1 semaine)
- connectors-api S-04/S-05 : Injection SSH (setupAutoKey + heredoc)
- connectors-api S-07 : Salt aleatoire pour scrypt
- connectors-api S-08 : Sandbox pour transform actions
- connectors-api S-09 : Signer le state OAuth
- ai-orchestrator S-04 :
shlex.quote() pour les commandes SSH
- ai-orchestrator S-06 : Validation upload (taille + type MIME)
- ai-orchestrator E-03 : Health endpoint robuste (try/except)
- ai-orchestrator E-05 : Ajouter num_ctx au type "generate"
- ulias-org 5.1/9.1 : Wrapper safe pour ws.send() + AbortController
- ulias-org 2.1/2.2 : Corriger IPs hardcodees et port fallback
Phase 3 : Stabilite (< 2 semaines)
- ai-orchestrator B-01 : asyncio.Lock() sur active_tools
- ai-orchestrator B-03 : Semaphore pour jobs cloud
- ai-orchestrator B-05 : Compteur de retry sur requeue
- ai-orchestrator V-03 : Reduire keep_alive sur GPU1
- ai-orchestrator V-05 : Preemption/unload avant dispatch exclusive
- ai-orchestrator E-02 : Reconnexion Redis/PG
- ulias-org 3.1 : Reduire timeout routing LLM a 90s
- ulias-org 10.1 : Retourner les bons codes HTTP d'erreur
- ulias-org-web P13 : Bouton reconnexion WS ou backoff infini
- ulias-org-web P18 : Confirmation avant suppression conversation
Phase 4 : Qualite (< 1 mois)
30-144. Tous les MOYENNE et BASSE restants.
RAPPORTS DETAILLES
Les rapports individuels avec tous les details (numeros de ligne, code, fix proposes) sont disponibles :
- connectors-api :
~/propositions/15-02-2026-18-00-audit-connectors-api.md
- ai-orchestrator : Rapport complet dans l'output de l'agent ac4c493
- ulias-org : Rapport complet dans l'output de l'agent a90f96e
- ulias-org-web : Rapport complet dans l'output de l'agent adb185e
- dashboard-33800 : Exploration partielle (agent a167c3f)
Audit realise par Claude Opus 4.6 - 15/02/2026 - Mode lecture seule