MVAESTECH
Guide .NET · 15 · Production

Publié le · par Mathieu Vaes

Sécurité

La sécurité est une propriété de l'architecture, pas une tâche de fin de projet. La plupart des failles viennent de défauts simples : secret commité, autorisation oubliée, dépendance vulnérable.

Chapitres du guide
En clair

La plupart des failles ne sont pas sophistiquées : un mot de passe dans le code, un endpoint oublié sans contrôle d'accès, une bibliothèque jamais mise à jour. Règle de base : tout est fermé par défaut, on n'ouvre que ce qui doit l'être, explicitement.

OWASP Top 10 côté .NET Confirmé

RisqueDéfense .NET
Contrôle d'accès défaillantRequireAuthorization() par défaut (FallbackPolicy), policies, vérifier que la ressource appartient à l'appelant (IDOR)
Défaillances cryptographiquesHTTPS + HSTS, Data Protection, jamais d'algorithme maison ; mots de passe hachés via Identity (PBKDF2) ou délégués à un IdP
InjectionRequêtes paramétrées (EF Core, Dapper avec paramètres), FromSql interpolé ; Razor encode le HTML par défaut
Conception non sécuriséeModélisation des menaces, rate limiting, limites de taille des requêtes
Mauvaise configurationPas de page d'exception développeur en production, en-têtes de sécurité, CORS restreint
Composants vulnérablesNuGet Audit (actif par défaut dans le SDK), Dependabot / Renovate, images de base patchées
Authentification défaillanteOIDC avec un fournisseur (Entra ID, Keycloak, Identity Platform), jetons courts, PKCE
SSRFListe blanche d'hôtes pour les URL fournies par l'utilisateur

Secrets Junior

EnvironnementOù
Poste de devdotnet user-secrets (hors du dépôt)
CISecrets du pipeline, idéalement fédération d'identité (OIDC) vers le cloud sans secret stocké
GCPSecret Manager, accès par compte de service
KubernetesExternal Secrets Operator ou CSI driver vers Secret Manager ; les Secret natifs ne sont qu'encodés en base64
Windows / IISVariables d'environnement du pool, gMSA pour SQL Server (aucun mot de passe)

Activez un scanner de secrets sur le dépôt (gitleaks, GitHub secret scanning). Un secret commité doit être révoqué, le réécrire dans l'historique ne suffit pas.

Authentification d'une API Confirmé

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o =>
    {
        o.Authority = "https://login.acme.fr/realms/shop";   // l'IdP publie ses clés (JWKS)
        o.Audience  = "shop-api";
        o.TokenValidationParameters.ClockSkew = TimeSpan.FromSeconds(30);
        o.MapInboundClaims = false;                           // garder les noms de claims d'origine
    });

builder.Services.AddAuthorization(o =>
    o.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
    // tout endpoint est protégé sauf [AllowAnonymous] explicite
// Autorisation au niveau de la ressource : l'utilisateur est authentifié, mais est-ce SA commande ?
var order = await db.Orders.FindAsync([id], ct);
if (order is null || order.CustomerId != user.CustomerId) return TypedResults.NotFound();
Piège
  • CORS AllowAnyOrigin + AllowCredentials : interdit par le navigateur et dangereux ; lister les origines.
  • Jeton stocké dans localStorage côté SPA : exposé au XSS. Préférer le pattern BFF (backend-for-frontend) avec cookie HttpOnly, Secure, SameSite.
  • Désérialisation : BinaryFormatter est supprimé depuis .NET 9 ; avec Newtonsoft.Json, ne jamais activer TypeNameHandling.All sur des entrées externes.
  • Messages d'erreur bavards : stack traces, noms de tables ou versions exposés au client.

À retenir

  • Tout est protégé par défaut, l'anonyme est l'exception explicite.
  • Aucun secret dans le code, l'image ou les logs ; identité fédérée partout où c'est possible.
  • Audit des dépendances dans chaque build, images de base mises à jour chaque mois.

Un projet .NET à cadrer ou à reprendre ?

API REST documentées et testées, applications ASP.NET MVC (y compris VB.NET), migration de services anciens vers une architecture claire : parlons de votre code.