Le Top 10 OWASP 2025 appliqué à ASP.NET Core : ce que le framework fait pour vous, et ce qu'il ne fait pas
L'OWASP, fondation qui publie des ressources ouvertes sur la sécurité applicative, a fait paraître en 2025 une nouvelle édition de son Top 10 des risques des applications web. ASP.NET Core règle d'office plusieurs de ces problèmes ; d'autres dépendent entièrement de vos choix. Cet article passe en revue les dix catégories et indique, pour chacune, ce qu'il faut vérifier dans une application .NET.
Le classement sert à prioriser, pas à certifier. Une application « conforme au Top 10 » n'existe pas : la liste résume les familles de failles les plus souvent constatées, elle ne remplace ni une analyse de risques ni un test d'intrusion.
A01 — Contrôle d'accès défaillant
C'est de nouveau la première catégorie. L'erreur typique : une page ou une API oubliée sans attribut [Authorize], ou un identifiant dans l'URL (/factures/1042) que l'on peut incrémenter pour lire les factures d'un autre client. La première parade est d'inverser la logique par défaut avec une stratégie de repli qui exige un utilisateur authentifié partout, les exceptions étant marquées [AllowAnonymous] :
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
La seconde est de vérifier, à chaque accès à une ressource, qu'elle appartient bien à l'utilisateur : filtrez la requête de base de données sur son identifiant ou utilisez l'autorisation basée sur les ressources décrite dans la documentation des stratégies d'autorisation. Un rôle « client » ne dit rien de la facture que ce client a le droit de voir.
A02 — Mauvaise configuration de sécurité
Le modèle de projet active la page d'exception détaillée uniquement en environnement Development. Vérifiez que la variable ASPNETCORE_ENVIRONMENT n'est pas restée à cette valeur en production : une pile d'appels affichée au public révèle chemins, versions et parfois chaînes de connexion. Activez HTTPS et HSTS (guide HTTPS), ajoutez les en-têtes de sécurité (politique de sécurité du contenu, X-Content-Type-Options, Referrer-Policy) et sortez les secrets des fichiers appsettings.json versionnés : en développement, le gestionnaire de secrets ; en production, variables d'environnement ou coffre de clés.
A03 — Défaillances de la chaîne d'approvisionnement logicielle
Nouvelle venue en 2025, cette catégorie vise les dépendances vulnérables ou compromises. Depuis le SDK .NET 8, dotnet restore interroge les bases de vulnérabilités et émet des avertissements NU1901 à NU1904 selon la gravité (voir l'audit des paquets NuGet). Traitez-les comme des erreurs dans l'intégration continue, activez les fichiers de verrouillage (packages.lock.json) pour que la version restaurée soit celle que vous avez testée, et limitez les sources de paquets autorisées. Les bibliothèques JavaScript copiées dans wwwroot/lib il y a des années méritent le même inventaire.
A04 — Défaillances cryptographiques
N'écrivez pas votre propre chiffrement. Pour protéger un jeton, un cookie ou une donnée temporaire, l'API de protection des données d'ASP.NET Core gère algorithmes et rotation des clés. Pensez à persister l'anneau de clés hors du serveur quand l'application tourne sur plusieurs instances, sinon les cookies émis par l'une seront illisibles par l'autre. Pour les mots de passe, ASP.NET Core Identity utilise une dérivation de clé lente et salée ; si vous migrez une vieille base contenant des empreintes MD5 ou SHA-1, prévoyez une ré-empreinte à la prochaine connexion de chaque utilisateur.
A05 — Injection
Razor encode par défaut tout ce qu'il affiche, ce qui neutralise l'essentiel des injections de script (prévention du XSS). Le danger revient avec @Html.Raw, avec les chaînes insérées dans un bloc <script> ou dans un attribut href sans validation du schéma. Côté base de données, Entity Framework Core paramètre ses requêtes LINQ, mais la méthode choisie pour le SQL brut compte :
// Sûr : l'interpolation devient un paramètre SQL
var clients = db.Clients.FromSql($"SELECT * FROM Clients WHERE Ville = {ville}");
// Dangereux : la chaîne est concaténée avant d'atteindre EF Core
var risque = db.Clients.FromSqlRaw("SELECT * FROM Clients WHERE Ville = '" + ville + "'");
Notre article SQL injection explained (en anglais) détaille le mécanisme avec ADO.NET.
A06 — Conception non sécurisée
Aucun réglage ne corrige une fonction mal pensée : réinitialisation de mot de passe par question secrète, remboursement validable sans second contrôle, export complet de la base accessible à tout agent. Cette catégorie appelle une revue de conception, idéalement avec une modélisation des menaces sur les parcours sensibles, avant le code.
A07 — Défaillances d'authentification
Identity propose le verrouillage de compte après plusieurs échecs, la confirmation de l'adresse électronique et l'authentification à deux facteurs ; ces options sont à activer et à paramétrer. Ajoutez une limitation de débit sur les points d'entrée sensibles, que le framework fournit depuis .NET 7 (intergiciel de limitation de débit) :
builder.Services.AddRateLimiter(o =>
{
o.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
o.AddFixedWindowLimiter("connexion", l =>
{
l.PermitLimit = 5;
l.Window = TimeSpan.FromMinutes(1);
});
});
// ...
app.UseRateLimiter();
app.MapRazorPages().RequireRateLimiting("connexion"); // ou sur la seule page de connexion
A08 — Défaillances d'intégrité des logiciels ou des données
Désérialiser des données non fiables avec BinaryFormatter était un classique des applications .NET Framework ; ce sérialiseur est désactivé puis retiré dans les versions récentes de .NET. Préférez System.Text.Json avec des types explicites. Les formulaires Razor Pages incluent automatiquement un jeton antifalsification qui protège contre la falsification de requête intersite ; ne le désactivez pas pour « faire marcher » un appel JavaScript, transmettez plutôt le jeton (documentation antifalsification).
A09 — Défaillances de journalisation et d'alerte
Journaliser les connexions réussies et échouées, les refus d'autorisation et les opérations sensibles, avec ILogger et des messages structurés, est la base ; être alerté quand ces événements s'accumulent est ce que l'édition 2025 ajoute explicitement. En France, gardez à l'esprit le RGPD : les journaux contiennent des données personnelles (adresse IP, identifiant), leur durée de conservation doit être définie et ils ne doivent jamais contenir de mot de passe ni de données de santé. Le guide RGPD du développeur de la CNIL consacre une fiche à la journalisation.
A10 — Mauvaise gestion des situations exceptionnelles
Dernière nouveauté de 2025 : les erreurs qui laissent l'application dans un état incohérent ou qui « échouent ouvertes ». Un bloc catch vide autour d'une vérification de droits, et l'accès est accordé par défaut. Centralisez la gestion avec UseExceptionHandler et des réponses ProblemDetails qui ne divulguent rien (gestion des erreurs), et faites en sorte qu'une exception pendant un contrôle de sécurité aboutisse à un refus.
Par où commencer
Pour une application existante, trois actions couvrent une bonne part du risque en une journée : poser la stratégie d'autorisation de repli et relister les pages anonymes, faire échouer l'intégration continue sur les vulnérabilités NuGet, et vérifier l'environnement et les en-têtes en production. Le reste se planifie, catégorie par catégorie, avec l'aide de la fiche de sécurité .NET de l'OWASP.
Références
- OWASP : Top 10 des risques des applications web (édition 2025)
- CNIL : Sécuriser vos sites web, vos applications et vos serveurs
- CNIL : Guide RGPD du développeur
- Microsoft Learn : Autorisation basée sur des stratégies et protection des données
- Microsoft Learn : Audit des dépendances de paquets