Introduction : pourquoi votre site PHP peut-il être piraté dès maintenant ?
\nImaginez la situation : vous avez créé un super site en PHP, un formulaire de contact, des commentaires, un espace personnel. Tout fonctionne. Mais un jour, vous vous connectez à l'admin et il n'y a plus rien. Ou pire : des publicités de casino apparaissent sur votre site, et Google a bloqué votre ressource. Cela vous dit quelque chose ? La racine du mal est un mauvais traitement des entrées utilisateur.
\nLa question "How can I sanitize user input with PHP?" est l'une des plus populaires sur Stack Overflow. Des milliers de développeurs trébuchent sur les mêmes râteaux. Dans cet article, nous analyserons les principales erreurs que même les programmeurs expérimentés commettent et montrerons comment les éviter. Vous apprendrez à vous protéger contre les XSS, les injections SQL et autres attaques. C'est parti !
\n\nErreur n°1 : Utiliser mysql_real_escape_string() pour tout et n'importe quoi
\nLa vieille école : de nombreux développeurs pensent encore qu'en enveloppant toutes les données dans mysql_real_escape_string(), le problème est résolu. C'est une grave erreur. Cette fonction est uniquement destinée à échapper les chaînes dans les requêtes SQL, et encore, pour l'extension obsolète mysql_*, qui a été supprimée dès PHP 7.
Exemple de code incorrect :
\n<?php\n$name = mysql_real_escape_string($_POST['name']);\n$query = "INSERT INTO users (name) VALUES ('$name')";\n$result = mysql_query($query);\n?>\nPourquoi c'est mauvais :
\n- \n
- La fonction ne protège pas contre les attaques XSS (par exemple, l'insertion de JavaScript). \n
- L'extension
mysql_*est obsolète et non sécurisée. \n - Vous mélangez la logique d'échappement avec la logique métier. \n
Comment corriger : utilisez les requêtes préparées (prepared statements) via PDO ou MySQLi. Et pour l'affichage des données à l'écran, faites un assainissement séparé.
\n\nErreur n°2 : Ignorer les attaques XSS lors de l'affichage des données
\nL'erreur la plus courante. Vous recevez des données, les enregistrez dans la base de données et les affichez simplement avec echo ou print. Et voilà : un attaquant peut insérer un script qui volera les cookies, redirigera l'utilisateur ou gâchera la mise en page.
Exemple de code vulnérable :
\n<?php\necho "<p>Bonjour, " . $_GET['name'] . " !</p>";\n?>\nSi dans l'URL on passe ?name=<script>alert('XSS')</script>, le script s'exécutera.
Solution : utilisez la fonction htmlspecialchars() avec le paramètre ENT_QUOTES :
<?php\n$name = htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');\necho "<p>Bonjour, " . $name . " !</p>";\n?>\nImportant : l'assainissement doit être fait au moment de l'affichage, pas lors de l'enregistrement. Si vous remplacez les caractères dans la base de données, vous perdrez les données originales.
\n\nErreur n°3 : Filtrage aveugle avec strip_tags()
\nBeaucoup pensent : "Oh, je vais simplement supprimer toutes les balises HTML et tout ira bien". Mais strip_tags() n'est pas une panacée. D'une part, elle ne supprime que les balises, mais laisse les attributs (par exemple, onclick). D'autre part, si vous devez autoriser certaines balises (comme <b> ou <i>), strip_tags() devient peu pratique.
Exemple :
\n<?php\n$comment = strip_tags($_POST['comment']);\necho $comment; // Supprimera <script>, mais laissera <a onclick="...">\n?>\nSolution : utilisez htmlspecialchars() pour le texte ordinaire ou des bibliothèques comme HTML Purifier si vous devez autoriser certaines balises. HTML Purifier vérifie non seulement les balises, mais aussi les attributs, les styles et même le CSS.
Erreur n°4 : Absence de validation des emails, URL et nombres
\nL'assainissement ne concerne pas seulement le XSS. Si vous attendez un email et que vous recevez la chaîne "123", cela peut provoquer des erreurs. Ou si vous enregistrez une URL sans vérification, un attaquant peut insérer javascript:alert(1).