11 KiB
📊 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é
// ❌ 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 :
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
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)
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
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)
-- 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)
- Authentification obligatoire sur toutes les routes
- Staff detection côté serveur (table staff_users)
- Filtrage org_id explicite dans toutes les requêtes
- URLs S3 pré-signées avec expiration (15 min)
- Routes staff protégées par
isStaffUser() - org_id non modifiable en UPDATE
- 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
- Audit complet (850+ lignes)
- Script SQL de vérification
- Scripts SQL de correction (prêts à l'emploi)
- Résumé exécutif (ce document)
🎯 Plan d'Action Recommandé
IMMÉDIAT (Aujourd'hui)
-
⚠️ Exécuter le script de vérification RLS
psql $DATABASE_URL -f scripts/verify-rls-facturation-informations.sql -
⚠️ 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)
- 🔴 Si RLS désactivé : Appliquer les corrections (scripts fournis)
- 🟡 Créer les index org_id pour performance
- ✅ Tester l'isolation entre organisations
MOYEN TERME (Ce mois)
- 🟡 Ajouter logging pour accès factures (compliance)
- ℹ️ Créer tests E2E pour facturation et informations
- ℹ️ 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.mdSECURITY_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)