espace-paie-odentas/SECURITY_SUMMARY_FACTURATION_INFORMATIONS.md
2025-10-17 13:02:39 +02:00

346 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 📊 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)