La catégorie A03:2021 de l'OWASP fait référence à l'une des failles de sécurité les plus critiques et omniprésentes : les injections. Ces vulnérabilités surviennent lorsque des données non fiables sont envoyées à un interpréteur comme partie d'une commande ou d'une requête.
Découvrez un cas d’attaque
En 2008, Heartland Payment Systems, un important opérateur bancaire américain, a subi une attaque informatique d’ampleur.
L'attaque contre Heartland a été initiée via une injection SQL, une méthode d'exploitation des applications web vulnérables qui ne filtrent, ni ne nettoient correctement les entrées utilisateur.
Dans le cas de Heartland, les attaquants, menés par Albert Gonzalez et deux complices russes non identifiés, ont utilisé une injection SQL pour installer un logiciel d'écoute (sniffer) sur les serveurs de l'entreprise.
L'impact de cette brèche sur Heartland a été dévastateur. L'entreprise a perdu sa conformité PCI DSS pendant quatre mois et a dû faire face à la perte de centaines de clients. Le coût total pour l'entreprise, incluant l'indemnisation des victimes, a dépassé les 200 millions de dollars.
Identifiez les différentes injections
Injection SQL
L'injection SQL, ou SQLi, est une technique d'attaque exploitant des vulnérabilités dans la gestion des entrées d'une application pour exécuter des commandes SQL malveillantes.
Cette pratique permet à un attaquant d'interagir directement avec la base de données de l'application, menant potentiellement à une variété de conséquences néfastes.
Ces conséquences peuvent inclure la manipulation ou le vol de données, la destruction de contenu ou même, dans des cas extrêmes, le contrôle complet de la base de données et du serveur sous-jacent.
Imaginons que votre application web utilise un formulaire de connexion où les utilisateurs entrent leur nom d'utilisateur et leur mot de passe. Lorsqu'un utilisateur soumet ce formulaire, l'application construit et exécute une requête SQL pour vérifier les identifiants. Une requête typique pourrait ressembler à ceci :
SELECT * FROM users WHERE username = '[username]' AND password = '[password]';
Dans un scénario d'attaque par injection SQL, plutôt que d'entrer un nom d'utilisateur légitime, l'attaquant pourrait saisir un payload tel que'OR '1'='1
. Lorsque l'application insère cette entrée dans la requête SQL, cela donne :
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '[password]';
Cette requête sera toujours vraie à cause de la condition '1'='1',
ce qui permet à l'attaquant de contourner le processus d'authentification. De plus, selon la nature de la requête et les permissions du serveur, l'attaquant pourrait être en mesure de réaliser des actions plus malveillantes, telles que l'extraction d'informations de la base de données, la modification ou la suppression de données.
Quels autres types d’attaque par injection existe-t-il ?
Attaque cross-site-scripting (XSS)
L'Injection Cross-Site Scripting, ou XSS, est une vulnérabilité de sécurité courante dans les applications web. Elle permet aux attaquants d'injecter des scripts malveillants, généralement en JavaScript, dans des pages web vues par d'autres utilisateurs. Ces scripts peuvent être utilisés pour voler des informations, manipuler l'affichage de la page ou rediriger l'utilisateur vers des sites malveillants.
Il existe principalement trois types d'attaques XSS : Stored, Reflected et DOM-based.
1. XSS Stockées (Stored XSS)
Le XSS stocké, aussi connu sous le nom de XSS persistant, se produit lorsque le script malveillant est permanent sur le site web cible. Prenons l'exemple d'un forum en ligne où les utilisateurs peuvent laisser des commentaires. Imaginons qu'un attaquant souhaite exploiter une vulnérabilité XSS stockée sur ce site. Il commence par rédiger un commentaire qui inclut un script JavaScript malveillant, tel que <script>alert('XSS détectée');</script>
. Ce script est conçu pour afficher une alerte sur le navigateur de tout utilisateur qui visualiserait le commentaire.
Lorsque l'attaquant soumet son commentaire, le script est enregistré avec le reste du texte du commentaire dans la base de données du forum. Chaque fois qu'un utilisateur consulte la page du forum contenant ce commentaire, le navigateur interprète le script comme une partie légitime du code HTML de la page et exécute le JavaScript inclus.
Dans cet exemple, le script affiche simplement une alerte, mais dans un scénario réel, il pourrait être utilisé pour des activités malveillantes plus graves. Par exemple, il pourrait rediriger l'utilisateur vers un site web malveillant, voler des cookies de session, ou même manipuler le contenu de la page pour tromper l'utilisateur (par exemple, en affichant de fausses instructions de connexion).
2. XSS Réfléchies (Reflected XSS)
Le XSS réfléchi se produit lorsque le script malveillant est reflété par le serveur web, généralement comme résultat d'une requête de navigateur. Par exemple, un attaquant pourrait envoyer un lien à une victime qui contient un script malveillant dans la requête. Lorsque la victime clique sur ce lien, le script est envoyé à votre serveur, qui le renvoie dans sa réponse.
Ce script s'exécute ensuite dans le navigateur de la victime. Le danger de ce type de XSS réside dans le fait qu'il nécessite une interaction de l'utilisateur, souvent obtenue par le biais de techniques d'ingénierie sociale.
Protégez votre application web des injections
Existe-t-il des moyens pour se protéger de ces attaques ?
Tout à fait, c’est ce que nous allons voir dans cette section !
Commençons par l’injection SQL. Dans la section précédente, nous avons vu l’exemple d’une requête SQL vulnérable aux injections SQL :
SELECT * FROM users WHERE username = '[username]' AND password = '[password]';
Pour contrer les injections SQL, on utilise les requêtes préparées. Cette méthode consiste à créer une requête SQL où les valeurs spécifiques sont remplacées par des placeholders.
Ensuite, ces valeurs sont liées à la requête de manière sécurisée, séparant ainsi les données des instructions SQL. Cela empêche l'exécution de code SQL malveillant. En PHP, cela s'effectue avec PDO ou MySQLi. Avec PDO, par exemple :
$pdo = new PDO($dsn, $user, $password);
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
Cette méthode assure que les valeurs fournies par l'utilisateur sont traitées uniquement comme des données, empêchant toute exécution de code malveillant.
Super, je peux me protéger de l’injection SQL, mais qu’en est-il de l’injection XSS ?
Le principal risque lorsqu’un attaquant parvient à exploiter une injection XSS est le vol de cookie. L'un des moyens les plus efficaces pour limiter le risque de vol de cookies est d'utiliser le flag HttpOnly
pour les cookies.
Ce flag, lorsqu'il est activé, empêche les scripts côté client d'accéder au cookie, réduisant ainsi le risque de vol de cookies via des scripts malveillants. Cela signifie que même si une attaque XSS réussit, l'attaquant ne pourra pas facilement dérober les cookies de l'utilisateur, qui contiennent souvent des informations de session critiques.
Imaginons que votre application web utilise le serveur web Apache. Afin de mettre en place le flag HttpOnly,
voici les étapes que vous pouvez suivre :
1. Activer le module mod_headers via la commande a2enmod headers
2. Ajouter cette directive à votre fichier apache2.conf :
<IfModule mod_headers.c> Header always edit Set-Cookie (.*) "$1; HttpOnly." </IfModule>
3. Redémarrer votre service apache service apache2 restart
Parmi les recommandations, voici les deux principales pour cette catégorie :
Validation stricte des entrées utilisateurs : Assurez-vous que toutes les entrées fournies par les utilisateurs sont validées en fonction de critères stricts. Cela signifie refuser toutes les données qui ne correspondent pas exactement au format attendu. Utilisez des expressions régulières et des listes blanches pour valider les formats de données acceptables et rejeter toute entrée suspecte.
Échappement des caractères spécifiques : Lorsque l'utilisation de requêtes paramétrées n'est pas possible, assurez-vous d'échapper systématiquement les caractères spéciaux dans les entrées utilisateurs qui sont ensuite utilisées dans des requêtes ou des commandes.
Des bibliothèques spécifiques à chaque langage de programmation sont disponibles pour échapper de manière sécurisée ces caractères.
En résumé
La catégorie A03:2021 de l'OWASP met en lumière le danger des injections, où des données non fiables sont utilisées pour exécuter des commandes malveillantes.
Les attaques d'injection comprennent l'injection SQL (SQLi), permettant l'accès et la manipulation de bases de données, et l'injection Cross-Site Scripting (XSS), qui cible les utilisateurs d'applications web.
Utilisez des requêtes préparées et la validation des entrées pour sécuriser vos applications contre l'injection SQL.
Adoptez des pratiques telles que l'échappement des caractères spéciaux, la mise en place du flag HttpOnly, la validation et la sanitisation des entrées pour prévenir les injections.
Les cheatsheet concernant la prévention des injections SQL et concernant la prévention des attaques Cross-Site Scripting partagent des astuces utiles pour éviter les injections
Le prochain chapitre abordera l'importance d'une conception réfléchie et sécurisée dans le développement d'applications web, un aspect fondamental pour prévenir les vulnérabilités avant même qu'elles ne se manifestent.