346 lines
11 KiB
Markdown
346 lines
11 KiB
Markdown
# 📊 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)
|