# 📊 Résumé Exécutif - Sécurité Facturation & Vos Informations **Date** : 16 octobre 2025 **Périmètre** : Pages `/facturation` et `/informations` **Statut Initial** : 🟡 **BON** (avec alerte critique sur organization_details) --- ## 🎯 Objectif de l'Audit Vérifier que les pages **Facturation** et **Vos informations** respectent les mêmes standards de sécurité que les autres écosystèmes audités (contrats, virements-salaires, cotisations). --- ## 📋 Périmètre Analysé ### Pages Client - ✅ `app/(app)/facturation/page.tsx` (362 lignes) - ✅ `app/(app)/informations/page.tsx` (257 lignes) ### APIs Client - ✅ `/api/facturation/route.ts` (186 lignes, GET) - ✅ `/api/informations/route.ts` (150 lignes, GET) - ✅ `/api/informations/productions/route.ts` (103 lignes, GET) ### APIs Staff (Bonus - Gestion Productions) - ✅ `/api/staff/productions/route.ts` (GET, POST) - ✅ `/api/staff/productions/[id]/route.ts` (GET, PATCH, DELETE) ### Tables Critiques - ⚠️ **invoices** (factures) - 🔴 **organization_details** (IBAN, emails, SIRET - **CRITIQUE**) - ⚠️ **productions** (spectacles) --- ## 🔍 Résultats de l'Audit ### ✅ Conformités Identifiées (10) | ID | Conformité | Statut | |----|------------|--------| | C1 | Authentification robuste (facturation) | ✅ Session requise | | C2 | Resolution org_id côté serveur (facturation) | ✅ `getClientInfoFromSession()` | | C3 | Filtrage org_id SEPA (facturation) | ✅ `.eq("org_id", ...)` | | C4 | Filtrage org_id invoices (facturation) | ✅ `.eq("org_id", ...)` | | C5 | S3 URLs sécurisées (facturation) | ✅ Pré-signées 15 min | | C6 | Authentification robuste (informations) | ✅ Session requise | | C7 | Filtrage org_id organization_details | ✅ `.eq("org_id", ...)` | | C8 | Filtrage org_id productions | ✅ `.eq("org_id", ...)` | | C9 | Staff-only routes protection | ✅ `isStaffUser()` | | C10 | Immutabilité org_id en UPDATE | ✅ Exclusion explicite | ### ⚠️ Vérifications Requises (3 critiques) | ID | Vérification | Criticité | Statut | |----|--------------|-----------|--------| | V1 | RLS sur `invoices` | 🔴 Critique | ⚠️ À vérifier | | V2 | RLS sur `organization_details` | 🔴 **CRITIQUE** | ⚠️ À vérifier | | V3 | RLS sur `productions` | 🟠 Modérée | ⚠️ À vérifier | ### 🟡 Optimisations Recommandées (2) | ID | Optimisation | Criticité | |----|--------------|-----------| | O1 | Index org_id pour performance RLS | 🟡 Faible | | O2 | Logging accès factures (audit) | 🟡 Faible | --- ## 🚨 Alerte CRITIQUE : organization_details ### Pourquoi est-ce critique ? La table `organization_details` contient **40+ colonnes de données sensibles** : **Données bancaires** : - 🔴 IBAN, BIC (coordonnées bancaires) **Données personnelles** : - 🔴 email_notifs, email_notifs_cc, email_signature - 🔴 prenom_contact, nom_contact, tel_contact - 🔴 prenom_signataire, nom_signataire, qualite_signataire **Identifiants officiels** : - 🔴 code_employeur, SIRET, SIREN - 🔴 RNA, TVA intracommunautaire - 🔴 Licence spectacles **Identifiants caisses** : - 🔴 URSSAF, Audiens, Congés Spectacles - 🔴 Pôle Emploi Spectacle, AFDAS, FNAS, FCAP ### Impact si RLS désactivé ```typescript // ❌ SANS RLS : Un attaquant pourrait faire const { data } = await supabase .from("organization_details") .select("iban, bic, email_notifs, siret, code_employeur"); // → Fuite MASSIVE de données : // - Toutes les coordonnées bancaires // - Tous les emails de contact // - Tous les codes employeurs et SIRET // → VIOLATION RGPD MAJEURE ``` --- ## 🛠️ Actions Réalisées ### 1. Script de Vérification **Fichier** : `scripts/verify-rls-facturation-informations.sql` Vérifie : - ✅ RLS activé sur les 3 tables - ✅ Politiques RLS existantes - ✅ Index sur org_id **À exécuter IMMÉDIATEMENT** : ```bash psql $DATABASE_URL -f scripts/verify-rls-facturation-informations.sql ``` ### 2. Documentation **Fichier** : `SECURITY_AUDIT_FACTURATION_INFORMATIONS.md` (850+ lignes) Contenu : - Architecture complète (2 écosystèmes) - 10 conformités identifiées - 3 vérifications requises (avec scripts SQL de correction) - Plan de correction en 4 phases - Matrice des risques --- ## 📊 Métriques de Sécurité ### Code Applicatif (🟢 EXCELLENT) | Aspect | Score | Détails | |--------|-------|---------| | Authentification | 10/10 | Session obligatoire, pas de bypass | | Filtrage org_id | 10/10 | Systématique sur tous les endpoints | | Staff detection | 10/10 | Table `staff_users`, pas de métadonnées client | | S3 Security | 10/10 | URLs pré-signées, expiration 15 min | | Validation données | 10/10 | org_id non modifiable, pagination limitée | ### Base de Données (⚠️ À VÉRIFIER) | Table | Sensibilité | RLS Vérifié | Risque | |-------|-------------|-------------|--------| | invoices | Haute | ❌ Non | 🔴 Élevé | | organization_details | **Critique** | ❌ Non | 🔴 **CRITIQUE** | | productions | Moyenne | ❌ Non | 🟠 Moyen | --- ## 🔐 Scripts de Correction (si RLS désactivé) ### Pour invoices ```sql ALTER TABLE invoices ENABLE ROW LEVEL SECURITY; CREATE POLICY "Users can view their org invoices" ON invoices FOR SELECT USING ( org_id IN ( SELECT org_id FROM organization_members WHERE user_id = auth.uid() ) ); ``` ### Pour organization_details (CRITIQUE) ```sql ALTER TABLE organization_details ENABLE ROW LEVEL SECURITY; CREATE POLICY "Users can view their org details" ON organization_details FOR SELECT USING ( org_id IN ( SELECT org_id FROM organization_members WHERE user_id = auth.uid() ) ); -- Optionnel : Permettre UPDATE aux admins CREATE POLICY "Admins can update their org details" ON organization_details FOR UPDATE USING ( org_id IN ( SELECT org_id FROM organization_members WHERE user_id = auth.uid() AND role IN ('ADMIN', 'SUPER_ADMIN') ) ); ``` ### Pour productions ```sql ALTER TABLE productions ENABLE ROW LEVEL SECURITY; CREATE POLICY "Users can view their org productions" ON productions FOR SELECT USING ( org_id IN ( SELECT org_id FROM organization_members WHERE user_id = auth.uid() ) ); ``` ### Pour toutes les tables (Staff bypass) ```sql -- Staff via service-role CREATE POLICY "Service role bypass" ON invoices FOR ALL USING (true) WITH CHECK (true) TO service_role; CREATE POLICY "Service role bypass" ON organization_details FOR ALL USING (true) WITH CHECK (true) TO service_role; CREATE POLICY "Service role bypass" ON productions FOR ALL USING (true) WITH CHECK (true) TO service_role; ``` --- ## ✅ Checklist Finale ### Sécurité Code (🟢 EXCELLENT) - [x] Authentification obligatoire sur toutes les routes - [x] Staff detection côté serveur (table staff_users) - [x] Filtrage org_id explicite dans toutes les requêtes - [x] URLs S3 pré-signées avec expiration (15 min) - [x] Routes staff protégées par `isStaffUser()` - [x] org_id non modifiable en UPDATE - [x] Pagination sécurisée (max 50/page) ### Base de Données (⚠️ EN ATTENTE) - [ ] RLS vérifié sur `invoices` → **ACTION REQUISE** - [ ] RLS vérifié sur `organization_details` → **ACTION REQUISE CRITIQUE** - [ ] RLS vérifié sur `productions` → **ACTION REQUISE** - [ ] Index org_id créés pour performance → Optionnel ### Documentation - [x] Audit complet (850+ lignes) - [x] Script SQL de vérification - [x] Scripts SQL de correction (prêts à l'emploi) - [x] Résumé exécutif (ce document) --- ## 🎯 Plan d'Action Recommandé ### IMMÉDIAT (Aujourd'hui) 1. ⚠️ **Exécuter le script de vérification RLS** ```bash psql $DATABASE_URL -f scripts/verify-rls-facturation-informations.sql ``` 2. ⚠️ **Analyser les résultats** - Si RLS désactivé → **CRITIQUE**, appliquer corrections immédiatement - Si RLS activé → Vérifier les politiques existantes ### COURT TERME (Cette semaine) 3. 🔴 **Si RLS désactivé** : Appliquer les corrections (scripts fournis) 4. 🟡 Créer les index org_id pour performance 5. ✅ Tester l'isolation entre organisations ### MOYEN TERME (Ce mois) 6. 🟡 Ajouter logging pour accès factures (compliance) 7. ℹ️ Créer tests E2E pour facturation et informations 8. ℹ️ Documenter le pattern de sécurité dans README.md --- ## 🏆 État Final Attendu : 🟢 **EXCELLENT** Après vérification et correction du RLS, l'écosystème **facturation/informations** sera : ### Architecture de Sécurité (4 couches) ``` ┌──────────────────────────────────────────┐ │ COUCHE 1 : Authentification │ │ - Session Supabase obligatoire │ │ - Token JWT dans requêtes │ └──────────────────────────────────────────┘ ↓ ┌──────────────────────────────────────────┐ │ COUCHE 2 : API Route │ │ - getClientInfoFromSession() │ │ - Staff detection (staff_users) │ │ - org_id resolution server-side │ └──────────────────────────────────────────┘ ↓ ┌──────────────────────────────────────────┐ │ COUCHE 3 : Filtrage Applicatif │ │ - .eq("org_id", clientInfo.id) │ │ - Requêtes filtrées systématiquement │ └──────────────────────────────────────────┘ ↓ ┌──────────────────────────────────────────┐ │ COUCHE 4 : Base de Données (RLS) │ │ - Row Level Security activé │ │ - Politiques is_member_of_org() │ │ - Service-role bypass pour staff │ └──────────────────────────────────────────┘ ↓ ┌──────────────────────────────────────────┐ │ COUCHE 5 : Index Performance │ │ - Index sur org_id (3 tables) │ │ - Performance RLS garantie │ └──────────────────────────────────────────┘ ``` ### Résultat Final - ✅ **Protection multi-couches** (5 niveaux) - ✅ **Isolation parfaite** entre organisations - ✅ **Données bancaires sécurisées** (IBAN/BIC) - ✅ **URLs S3 pré-signées** avec expiration - ✅ **Conforme RGPD** (données personnelles protégées) - ✅ **Performance optimale** (index + RLS) --- ## 📞 Contact & Références **Audit complet** : `SECURITY_AUDIT_FACTURATION_INFORMATIONS.md` **Script SQL** : `scripts/verify-rls-facturation-informations.sql` **Audits précédents** : - `SECURITY_AUDIT_CONTRATS.md` - `SECURITY_AUDIT_VIREMENTS_COTISATIONS.md` **Date de création** : 16 octobre 2025 **Auteur** : GitHub Copilot **Statut** : ⚠️ EN ATTENTE de vérification RLS --- **⚠️ ACTION IMMÉDIATE REQUISE** : Exécuter le script de vérification RLS avant mise en production. **Niveau de sécurité** : 🟡 BON → 🟢 **EXCELLENT** (après vérification RLS)