LAB-AUTH-001 · 7 novembre 2026 · Version 1

Revue .NET : contrôle d’accès à une facture

Démonstration locale sur du code et des données synthétiques. Ce rapport décrit un exercice interne, sans mission client ni validation indépendante.

Périmètre et règle métier

Programme console C# ciblant .NET 10, sans dépendance NuGet tierce, sans service exposé, sans données réelles. Une facture fictive n’est accessible qu’à son propriétaire dans son organisation. Les identités ClaimsPrincipal sont construites par les tests ; elles ne proviennent pas d’un fournisseur d’identité.

Le périmètre couvre la fonction de lecture et dix scénarios. Il exclut l’authentification réelle, les JWT, les middlewares ASP.NET, les requêtes Entity Framework, la configuration Azure et tout système tiers.

Constat : authentifié ne signifie pas autorisé

La version initiale vérifie que l’utilisateur est authentifié, puis recherche la facture uniquement par son identifiant. Le propriétaire et l’organisation ne sont pas contrôlés. Dans le laboratoire, une identité d’une autre organisation ou d’un autre propriétaire reçoit donc les données fictives.

Risque illustré : lecture non autorisée entre utilisateurs ou organisations. Impact potentiellement élevé dans un système contenant des factures réelles ; aucun score CVSS de production n’est attribué à cet exemple synthétique. La précondition du scénario est une identité authentifiée et un identifiant de facture existant.

Correction

La version corrigée exige une seule valeur non vide pour les claims sub et tenant_id, puis limite la recherche à l’identifiant, à l’organisation et au propriétaire, avec une comparaison explicite. Une ressource inexistante ou hors périmètre retourne le même statut 404, sans corps de facture.

Les identités absentes sont refusées (401), les claims absents ou ambigus sont refusés (403), un identifiant non positif est rejeté (400). En production, les claims doivent provenir d’une authentification validée côté serveur et la restriction doit être appliquée à la requête de données.

Résultats observés — mêmes assertions avant et après

Statut attendu et statuts observés ; chaque test vérifie aussi le contenu retourné.
ScénarioAttenduAvantAprès
owner_can_read200200 — OK200 — OK
other_tenant_denied404200 — Échec404 — OK
other_owner_denied404200 — Échec404 — OK
anonymous_denied401401 — OK401 — OK
missing_tenant_denied403200 — Échec403 — OK
missing_subject_denied403200 — Échec403 — OK
duplicate_tenant_denied403200 — Échec403 — OK
unknown_record_not_found404404 — OK404 — OK
invalid_id_rejected400400 — OK400 — OK
tenant_case_not_normalized404200 — Échec404 — OK

Avant : 4 réussites, 6 échecs, code de sortie 1 attendu. Après : 10 réussites, 0 échec, code de sortie 0. Les résultats démontrent ces dix assertions uniquement.

Reproduire les résultats

Téléchargez et extrayez le laboratoire. Avec le SDK .NET 10, depuis le dossier extrait :

dotnet build -c Release
dotnet run -c Release --no-build -- --before
dotnet run -c Release --no-build

Le premier lancement doit échouer avec le code 1 : il expose les défauts attendus du code pédagogique initial. Le second doit réussir avec le code 0. Ne déployez pas la version initiale en service accessible.

Résultats horodatés et empreintes SHA-256 · Journal de compilation

Limites et suites nécessaires

Cette validation unitaire n’évalue pas une API en fonctionnement. Pour un projet réel : vérifier la chaîne d’authentification, les rôles métier, le filtrage des données, les autres chemins d’accès et les erreurs ; compléter par des tests d’intégration et des contrôles adaptés au périmètre autorisé.

La non-divulgation du corps de réponse ne démontre pas l’absence de canaux auxiliaires, de fuite dans les journaux ou de failles dans d’autres fonctions. Les résultats sont auto-produits, sans revue indépendante. Ce laboratoire peut illustrer une démarche de remédiation, pas remplacer des références professionnelles vérifiables.

Revenir aux preuves et au modèle d’autorisation →