|
| 1 | +# Sécurité — TableMasterApi |
| 2 | + |
| 3 | +> Document de référence Bloc 2 — C2.2.3 (sécurisation du code source) du RNCP39583. |
| 4 | +> Mapping des **mesures concrètes** dans le code de l'API face à l'**OWASP Top 10 (édition 2021)**. |
| 5 | +
|
| 6 | +## Synthèse |
| 7 | + |
| 8 | +| Faille OWASP | Couverture | Localisation | |
| 9 | +| --- | :---: | --- | |
| 10 | +| A01 Broken Access Control | ✅ | `[Authorize]` + `ICurrentUserService` | |
| 11 | +| A02 Cryptographic Failures | ✅ | TLS (Nginx), `BCrypt`/hash mot de passe, JWT signé | |
| 12 | +| A03 Injection | ✅ | Dapper paramètres nommés, jamais de concat | |
| 13 | +| A04 Insecure Design | ✅ | Architecture en couches, threat-model documenté | |
| 14 | +| A05 Security Misconfiguration | ✅ | Secrets hors code, Docker minimal, headers Nginx | |
| 15 | +| A06 Vulnerable Components | ⚠️ | Dependabot à activer (manuel pour l'instant) | |
| 16 | +| A07 Identification & Auth Failures | ✅ | JWT court + refresh token rotation | |
| 17 | +| A08 Software & Data Integrity | ✅ | Migrations DbUp signées en source, CI vérifiée | |
| 18 | +| A09 Logging & Monitoring | ⚠️ | `ILogger` présent, Sentry à brancher | |
| 19 | +| A10 Server-Side Request Forgery | ✅ | Aucun proxy d'URL utilisateur côté API | |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +## A01 — Broken Access Control |
| 24 | + |
| 25 | +**Risque** : un utilisateur peut accéder à des ressources qui ne lui appartiennent pas. |
| 26 | + |
| 27 | +**Mesures :** |
| 28 | +- Tous les controllers sensibles décorés `[Authorize]`. |
| 29 | +- L'identité courante est résolue via `ICurrentUserService` (claim `sub`) — jamais via paramètre client. |
| 30 | +- Les méthodes "mes ressources" (`/Reservation/My`, etc.) filtrent côté DAL sur `current_user.Id`. |
| 31 | +- Les opérations sur le restaurant vérifient que `restaurant.UserId == currentUser.Id` avant write/update/delete. |
| 32 | + |
| 33 | +**À auditer périodiquement** : chaque nouveau controller doit prouver son contrôle d'accès dans la PR. |
| 34 | + |
| 35 | +## A02 — Cryptographic Failures |
| 36 | + |
| 37 | +**Risque** : transport en clair, secrets stockés faiblement. |
| 38 | + |
| 39 | +**Mesures :** |
| 40 | +- TLS terminé au reverse-proxy Nginx (Let's Encrypt) ; HSTS activé. |
| 41 | +- Mots de passe utilisateurs hashés (jamais stockés en clair). |
| 42 | +- JWT signés HS256 avec secret stocké en variable d'environnement (`Jwt:Key`) — jamais commité. |
| 43 | +- Clé Firebase Admin (`tablemaster-firebase.json`) hors Git, montée en volume Docker. |
| 44 | + |
| 45 | +**Contre-exemple à ne pas faire** : `appsettings.json` ne doit contenir aucun secret de production. |
| 46 | + |
| 47 | +## A03 — Injection |
| 48 | + |
| 49 | +**Risque** : injection SQL via paramètres utilisateur. |
| 50 | + |
| 51 | +**Mesures :** |
| 52 | +- 100 % des requêtes utilisent **Dapper avec paramètres nommés** : |
| 53 | + ```csharp |
| 54 | + await connection.QueryAsync<UserOut>( |
| 55 | + "SELECT * FROM Users WHERE Email = @Email", |
| 56 | + new { Email = email }); |
| 57 | + ``` |
| 58 | +- **Aucune** concaténation de string avec entrée utilisateur dans les DAL (`TableMasterApi/DAL/`). |
| 59 | +- Type handlers Dapper personnalisés (ex. `PostgresTimeSpanHandler`) maîtrisent les conversions sensibles. |
| 60 | + |
| 61 | +## A04 — Insecure Design |
| 62 | + |
| 63 | +**Mesures :** |
| 64 | +- Architecture en couches : Controllers (HTTP) → Services (logique) → DAL (données). |
| 65 | +- Controllers minces : aucun accès BDD ni logique métier complexe. |
| 66 | +- DAL via interfaces (`DAL/Interfaces/`) — mockables, testables, substituables. |
| 67 | +- Schéma BDD piloté par migrations versionnées (`sql-scripts/`). |
| 68 | +- Threat-model documenté dans le dossier de cadrage Bloc 1. |
| 69 | + |
| 70 | +## A05 — Security Misconfiguration |
| 71 | + |
| 72 | +**Mesures :** |
| 73 | +- Image Docker basée sur `mcr.microsoft.com/dotnet/aspnet` (officielle, minimale). |
| 74 | +- `appsettings.Development.json` jamais déployé en prod (CI build en `Release`). |
| 75 | +- Swagger activé uniquement en dev ou si `Features:EnableSwagger=true` — désactivé par défaut en prod. |
| 76 | +- Reverse-proxy Nginx avec headers : `X-Content-Type-Options`, `Strict-Transport-Security`, `Referrer-Policy`. |
| 77 | +- Health checks `/health` et `/ready` séparés des endpoints métier. |
| 78 | + |
| 79 | +## A06 — Vulnerable and Outdated Components |
| 80 | + |
| 81 | +**Mesures :** |
| 82 | +- `dotnet list package --vulnerable` lancé avant chaque release. |
| 83 | +- Versions NuGet pinnées dans le `.csproj`. |
| 84 | + |
| 85 | +**À automatiser** : activer **Dependabot** ou **Renovate** sur le repo GitHub pour PR automatiques de mise à jour. |
| 86 | + |
| 87 | +## A07 — Identification & Authentication Failures |
| 88 | + |
| 89 | +**Mesures :** |
| 90 | +- JWT à courte durée (~15 min) + refresh token long avec **rotation à chaque usage**. |
| 91 | +- Refresh tokens persistés en BDD avec date d'expiration + `IsRevoked` (`AuthDAL`). |
| 92 | +- Logout : révocation côté serveur (DeviceToken supprimé) + suppression côté client. |
| 93 | +- `JwtService` centralise génération + validation — aucun fork dans les controllers. |
| 94 | + |
| 95 | +**Améliorations à venir** : rate limiting sur `/Auth` (ASP.NET Rate Limiting middleware) pour mitiger le brute-force. |
| 96 | + |
| 97 | +## A08 — Software & Data Integrity Failures |
| 98 | + |
| 99 | +**Mesures :** |
| 100 | +- Migrations DbUp embarquées comme **ressources** dans l'assembly (`<EmbeddedResource>`) → impossibles à modifier sans rebuild. |
| 101 | +- Scripts SQL numérotés et **idempotents** quand possible. |
| 102 | +- CI lance `dotnet test` avant tout build d'image Docker → pas d'image publiée si tests rouges. |
| 103 | + |
| 104 | +## A09 — Security Logging & Monitoring Failures |
| 105 | + |
| 106 | +**État actuel :** |
| 107 | +- `ILogger<T>` injecté dans services et controllers sensibles (Auth, JWT, refresh). |
| 108 | +- Logs structurés via le provider par défaut ASP.NET. |
| 109 | + |
| 110 | +**À compléter** : |
| 111 | +- Brancher **Sentry .NET SDK** dans `Program.cs` pour collecter exceptions + traces. |
| 112 | +- Ajouter un middleware de `correlationId` pour tracer une requête de bout en bout. |
| 113 | +- Activer audit log sur opérations sensibles (login, refresh, logout, delete account). |
| 114 | + |
| 115 | +## A10 — Server-Side Request Forgery |
| 116 | + |
| 117 | +**État** : l'API ne consomme **pas d'URL fournie par l'utilisateur** côté serveur. Les seules sorties HTTP sont : |
| 118 | +- Firebase Admin (FCM) — destination figée dans la lib. |
| 119 | +- Google Maps (si utilisé côté serveur) — endpoint figé. |
| 120 | + |
| 121 | +Aucune fonctionnalité de type "fetch URL", "import depuis lien", "webhook entrant" → faible surface SSRF. |
| 122 | + |
| 123 | +--- |
| 124 | + |
| 125 | +## Audit & révision |
| 126 | + |
| 127 | +| Quand | Action | |
| 128 | +| --- | --- | |
| 129 | +| Avant chaque release majeure | Lancer `dotnet list package --vulnerable --include-transitive` | |
| 130 | +| À chaque PR | CI vérifie build + tests + scan image Docker (à brancher) | |
| 131 | +| Trimestriel | Audit OWASP ZAP en mode automatisé contre l'API de staging | |
| 132 | +| Annuel | Revue manuelle de ce document — corriger les points vieillis | |
| 133 | + |
| 134 | +## Contact |
| 135 | + |
| 136 | +Découverte d'une vulnérabilité → ouvrir un Security Advisory privé sur GitHub, **ne pas** ouvrir d'issue publique. |
0 commit comments