C# en action : comment protéger le code contre les injections SQL et les attaques XSS

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Préface : pourquoi la sécurité n'est pas une option, mais une hygiène de base

\n\n

Imaginez : vous développez un super service web en C#. Tout fonctionne parfaitement — les utilisateurs s'inscrivent, laissent des commentaires, recherchent des produits. Puis arrive « le hacker Vasya » (qui en réalité a simplement copié un script trouvé sur Internet) — et il vide toute la base de données. Ou pire encore, il insère dans votre page un script qui vole les cookies de tous les visiteurs.

\n\n

Cela ressemble à un scénario de film d'horreur ? Pourtant, cela arrive tous les jours. Selon les statistiques de l'OWASP, les injections (SQL, XSS, LDAP) figurent dans le top 3 des vulnérabilités les plus dangereuses des applications web. Et C#, malgré toute sa fiabilité, ne vous offre pas de bouclier d'immunité par défaut.

\n\n

Dans cet article, nous allons décortiquer les deux attaques les plus courantes — les injections SQL et le XSS (cross-site scripting). Vous n'aurez pas seulement de la théorie, mais des techniques de défense concrètes en C# avec des exemples de code réels. C'est parti !

\n\n

Injections SQL : quand l'utilisateur devient un hacker

\n\n

À quoi cela ressemble en pratique

\n\n

Supposons que vous ayez une simple connexion à un système. L'utilisateur saisit un identifiant et un mot de passe, et vous construisez la requête ainsi :

\n\n
string login = txtLogin.Text;\nstring password = txtPassword.Text;\nstring query = "SELECT * FROM Users WHERE Login = '" + login + "' AND Password = '" + password + "'";\nSqlCommand cmd = new SqlCommand(query, connection);
\n\n

Cela vous semble logique ? Erreur ! Si un attaquant saisit dans le champ identifiant : ' OR 1=1 --, la requête devient :

\n\n
SELECT * FROM Users WHERE Login = '' OR 1=1 --' AND Password = '...'
\n\n

Tout ce qui suit -- est un commentaire. La condition 1=1 est toujours vraie. La requête renvoie tous les utilisateurs, et l'authentification est réussie. Et si, au lieu d'un commentaire, on insère DROP TABLE Users ? Adieu, base de données.

\n\n

Protection n°1 : les requêtes paramétrées (votre bouclier principal)

\n\n

La meilleure protection contre les injections SQL est de ne jamais concaténer manuellement des chaînes. Utilisez des paramètres. Le serveur SQL échappe lui-même les caractères dangereux, et votre base de données reçoit les données comme des valeurs, et non comme du code.

\n\n
string login = txtLogin.Text;\nstring password = txtPassword.Text;\n\nstring query = "SELECT * FROM Users WHERE Login = @Login AND Password = @Password";\n\nusing (SqlConnection conn = new SqlConnection(connectionString))\n{\n    SqlCommand cmd = new SqlCommand(query, conn);\n    cmd.Parameters.AddWithValue("@Login", login);\n    cmd.Parameters.AddWithValue("@Password", password);\n    \n    conn.Open();\n    SqlDataReader reader = cmd.ExecuteReader();\n    // traitement du résultat\n}
\n\n

Notez bien : @Login et @Password sont des paramètres. Même si l'utilisateur saisit '; DROP TABLE Users; --, le SGBD interprétera cela comme une simple chaîne, et non comme du code. Sûr et élégant.

\n\n

Protection n°2 : les procédures stockées

\n\n

Un autre outil puissant : les procédures stockées. Elles protègent non seulement contre les injections, mais améliorent aussi les performances (les plans d'exécution sont mis en cache).

\n\n
-- SQL Server\nCREATE PROCEDURE GetUserByLogin\n    @Login NVARCHAR(50)\nAS\nBEGIN\n    SELECT * FROM Users WHERE Login = @Login\nEND
\n\n
// Code C#\nusing (SqlConnection conn = new SqlConnection(connectionString))\n{\n    SqlCommand cmd = new SqlCommand("GetUserByLogin", conn);\n    cmd.CommandType = CommandType.StoredProcedure;\n    cmd.Parameters.AddWithValue("@Login", inputLogin);\n    \n    conn.Open();\n    // ...\n}
\n\n

Protection n°3 : Entity Framework et les ORM

\n\n

Si vous utilisez Entity Framework (ou tout autre ORM), vous êtes déjà partiellement protégé. EF génère automatiquement des requêtes paramétrées. Mais attention : les requêtes SQL brutes via EF (méthode FromSqlRaw) reviennent à faire de la concaténation. Restez vigilant !

\n\n
// MAUVAIS :\nvar users = context.Users.FromSqlRaw("SELECT * F                

Blogs

Book Recommendations