Skip to content

Rapport d'audit securite — Heriade (Addin + Backend)

Date : 2026-03-11 Auditeur : Claude Code (security-audit skill) Contexte : Production Scope : Audit complet (Addin Vue.js + Backend NestJS)

Resume executif

Le projet presente des fondations solides (JWT Supabase, Prisma parametrise, validation SQL des identifiants, multi-tenant scoping), mais souffre de lacunes critiques pour un deploiement production : CORS ouvert sans restriction, endpoints sensibles sans authentification (upload, enterprises, roles), cle de chiffrement avec fallback hardcode, et absence de rate limiting. 8 findings critiques necessitent une correction immediate.


Resultats

CRITIQUE — Corriger immediatement

#VulnerabiliteOWASPCWEFichier:ligneImpactFix recommande
1CORS sans restrictionapp.enableCors() sans aucune configuration autorise toutes les originesA05CWE-942back/src/main.ts:32Tout site peut envoyer des requetes API avec les credentials de l'utilisateurConfigurer origin: [process.env.FRONT_URL, process.env.ADDIN_URL], credentials: true, methods et allowedHeaders restreints
2Upload sans authentification — 4 endpoints d'upload/listing de fichiers n'ont aucun @UseGuards(AuthGuard)A01CWE-434back/src/upload/upload.controller.ts:10-36Upload de fichiers arbitraires par n'importe qui, listing des fichiers publics, DoS via fichiers volumineuxAjouter @UseGuards(AuthGuard) sur tous les endpoints + validation de type MIME + limite de taille
3Endpoints entreprises publics — GET /enterprises, /enterprises/:id, /enterprises/:id/users sans AuthGuardA01CWE-200back/src/enterprise/enterprise.controller.ts:10-23Enumeration de toutes les entreprises et utilisateurs du systemeAjouter @UseGuards(AuthGuard) et filtrer par enterprise de l'utilisateur
4Endpoint roles public — GET /roles sans AuthGuardA01CWE-200back/src/role/role.controller.ts:9-12Enumeration des roles du systeme (reconnaissance)Ajouter @UseGuards(AuthGuard)
5Cle de chiffrement hardcodee — Fallback 'default_secret_key' si ENCRYPTION_KEY absentA02CWE-321back/utils/external-db/encryptHelper.ts:4Tous les mots de passe BDD externes dechiffrables avec une cle connueRendre ENCRYPTION_KEY obligatoire, throw si absent ou < 32 chars
6Headers de securite absents — Pas de Helmet : ni CSP, ni HSTS, ni X-Frame-Options, ni X-Content-Type-OptionsA05CWE-693back/src/main.tsClickjacking, MIME sniffing, pas de HSTS, pas de CSPnpm i helmet puis app.use(helmet())
7Swagger expose en productionSwaggerModule.setup('api', app, document) sans condition d'environnementA05CWE-215back/src/main.ts:57-58API surface completement visible (endpoints, parametres, schemas)Conditionner a process.env.NODE_ENV !== 'production'
8SSRF via connexion manuellemanual-connect/* accepte n'importe quel host:port fourni par l'utilisateurA10CWE-918back/src/data-pivot/data-pivot.service.ts:176-204Scan reseau interne, acces metadata AWS (169.254.169.254), pivot vers BDD internesBloquer IPs privees/localhost/link-local, whitelist de ports, ou supprimer la connexion manuelle

HAUTE — Corriger avant mise en production

#VulnerabiliteOWASPCWEFichier:ligneImpactFix recommande
9IDOR sur PUT responsessaveRecordings et updateResponse n'injectent pas @CurrentUser(), aucune verification de proprieteA01CWE-639back/src/response/response.controller.ts:66-75Un utilisateur authentifie peut modifier n'importe quelle reponse par UUIDAjouter @CurrentUser() user et verifier l'acces dans le service
10Pas de rate limiting — Aucun @nestjs/throttler ou equivalent dans le codebaseA07CWE-307GlobalBrute force sur login, enumeration, DoS sur les endpointsInstaller @nestjs/throttler, configurer globalement + limits specifiques sur auth
11Body parser 256 MB — Limite de requete excessiveA04CWE-770back/src/main.ts:46-47DoS par envoi de payloads volumineux, exhaustion memoireReduire a 10-50 MB pour JSON, utiliser multer pour les uploads avec limites separees
12JWT stocke en localStorage — Tokens access + refresh en localStorage, vulnerable au XSSA07CWE-522addin/src/shared/authService.ts:23-24,80-81Si XSS present, vol de tokens et compromission de compteAttenuer via CSP strict ; pour l'addin Office le risque est reduit par le sandbox, mais reste une mauvaise pratique
13Echecs d'auth non logges — Aucun log des tentatives echouees avec contexte (IP, user_id)A09CWE-778back/src/common/guards/authGuard.ts:155-156,218-237Impossible de detecter les attaques brute force ou les tentatives d'intrusionAjouter this.logger.warn(...) sur chaque point d'echec avec IP et contexte

MOYENNE — A planifier

#VulnerabiliteOWASPCWEFichier:ligneImpactFix recommande
14LIMIT interpole en stringSELECT TOP ${limit} / LIMIT ${limit} sans parametrisationA03CWE-89back/src/data-pivot/data-pivot.service.ts:310,312Risque faible (borne par Math.min/max), mais viole le principe de parametrisationUtiliser des parametres prepares pour la clause LIMIT
15Pas de validation DTOlimit?: number dans le body sans class-validatorA03CWE-20back/src/data-pivot/data-pivot.controller.ts:41,67Type coercion JS, NaN, Infinity possibles avant le clamping serviceCreer un DTO avec @IsOptional() @IsNumber() @Min(1) @Max(100000)
16MSSQL trustServerCertificate: true — Desactive la verification TLS pour SQL ServerA02CWE-295back/utils/external-db/dialectHelper.ts:126MITM possible sur connexions SQL ServerConfigurer encrypt: true, trustServerCertificate: false en production
17Redis localhost fallbackprocess.env.REDIS_HOST || 'localhost' sans validationA05CWE-215back/src/app.module.tsCache non fonctionnel en multi-serveur si env var manquanteThrow en production si REDIS_HOST absent

BASSE / Informationnel

#ObservationOWASPFichier:ligneRecommandation
18Regex identifiants SQL accepte espaces et points^[a-zA-Z_][a-zA-Z0-9_. ]*$A03back/utils/external-db/pivotQuery.ts:8Mitige par le quoting correct ; restreindre si les noms avec espaces ne sont pas necessaires
19Credentials de test dans docker-compose — Mots de passe en clair dans le fichier compose de testA02addin/docker-test-dbs/docker-compose.ymlUtiliser un .env.docker avec env_file:
20Source maps desactivees en proddevtool: isDev ? "source-map" : falseA05addin/webpack.config.js:101Deja correctement configure

Dependances et CVE

Addin (npm audit) : 0 vulnerabilites trouvees.

Backend (yarn audit) : 160 vulnerabilites trouvees :

  • 10 Critical
  • 73 High
  • 36 Moderate
  • 41 Low

Principale CVE identifiee : file-type (boucle infinie sur input ASF malformed, affecte @nestjs/common et @swc/cli). Patch disponible : &gt;=21.3.1.

Action recommandee : Executer yarn audit fix et mettre a jour les packages critiques. Les CVE critiques/high doivent etre evaluees individuellement.

Git history : Aucun secret committe dans l'historique (git log --all --source -- '*.env' '*.key' '*.pem' '*.secret' — resultat vide).


Points positifs

  • SQL parametrise (Prisma.sql) : Toutes les requetes Prisma utilisent des template tags parametrises (A03)
  • Validation SQL des identifiants : quoteIdentifier() avec regex + echappement par dialect (A03)
  • Whitelist des agregations : Seuls SUM/AVG/COUNT/MIN/MAX sont autorises (A03)
  • Multi-tenant scoping : resolveConnection() filtre par enterprise_id du JWT (A01)
  • JWT verification robuste : Signature HMAC-SHA256 + comparaison timing-safe + verification expiration (A07)
  • Chiffrement AES-256-CTR : Mots de passe BDD externes chiffres au repos (A02)
  • Connexions avec timeout : connectionTimeoutMillis: 10_000 sur toutes les BDD (A04)
  • ValidationPipe + whitelist : whitelist: true, transform: true filtre les proprietes inattendues (A03)
  • Source maps off en prod : Pas d'exposition du code source (A05)
  • Pas de v-html : Aucune directive v-html dans les composants Vue (A03)
  • Pas d'eval/exec : Aucun usage de eval(), exec(), Function() (A03)
  • .env dans .gitignore : Fichiers d'environnement non committes (A02)
  • Logout nettoie localStorage : signOut() supprime tokens + appelle Supabase (A07)
  • Sanitisation des noms de feuilles Excel : Caracteres invalides filtres, longueur tronquee a 31 (A03)

Score global

Categorie OWASPScoreJustification
A01 - Broken Access Control3/10Endpoints sans auth (upload, enterprises, roles), IDOR sur responses
A02 - Cryptographic Failures6/10AES-256 en place mais cle fallback hardcodee, MSSQL sans TLS
A03 - Injection8/10Requetes parametrisees, validation identifiants, pas de XSS
A04 - Insecure Design5/10Pas de rate limiting, body 256MB, SSRF possible
A05 - Security Misconfiguration2/10CORS *, pas de Helmet, Swagger en prod
A06 - Vulnerable Components4/10160 vulns dans le backend (yarn audit)
A07 - Auth Failures6/10JWT correct mais pas de rate limiting, tokens en localStorage
A08 - Software & Data Integrity7/10Pas de SRI necessaire (pas de CDN), webhooks N/A
A09 - Logging & Monitoring3/10Logs basiques, echecs auth non traces, pas d'alerting
A10 - SSRF3/10Connexion manuelle sans filtrage d'IP/port

Score global : 4.5/10

Le projet a de bonnes bases techniques (SQL parametrise, JWT, multi-tenant), mais les lacunes en configuration de securite (CORS, headers, endpoints non proteges) et l'absence de defense en profondeur (rate limiting, logging securite, filtrage SSRF) le rendent non deplorable en production en l'etat.


Prochaines etapes

PrioriteActionEffort estimeFichier(s)
P0Configurer CORS avec whitelist d'origines~30 minmain.ts
P0Ajouter @UseGuards(AuthGuard) sur upload, enterprise, role controllers~1h3 controllers
P0Installer + configurer Helmet~15 minmain.ts
P0Rendre ENCRYPTION_KEY obligatoire (throw si absent)~15 minencryptHelper.ts
P0Desactiver Swagger en production~5 minmain.ts
P1Ajouter @CurrentUser() sur PUT responses (saveRecordings, update) + verif acces~1hresponse.controller.ts, response.service.ts
P1Installer @nestjs/throttler + configurer rate limiting~1happ.module.ts, controllers
P1Bloquer IPs privees/localhost dans connexions manuelles~2hdata-pivot.service.ts
P1Ajouter logging des echecs d'auth (IP, user_id, raison)~1hauthGuard.ts
P2Reduire bodyParser.limit a 10-50 MB~5 minmain.ts
P2Creer DTOs avec class-validator pour data-pivot~1hdata-pivot.controller.ts
P2yarn audit fix + mise a jour packages critiques~2hpackage.json
P2Parametriser LIMIT dans les requetes SQL~30 mindata-pivot.service.ts

Avertissement

Ce rapport a ete genere par un outil automatise (Claude Code) et constitue une aide a l'audit, pas un audit professionnel certifie. Les findings doivent etre relus et valides par un developpeur ou un expert securite avant toute action corrective. Certains resultats peuvent etre des faux positifs ou ne pas s'appliquer a votre contexte specifique. Ne transmettez pas ce rapport tel quel a une equipe technique sans l'avoir prealablement verifie.