Arrêtez!
Vous faites une erreur ici. Oh, non, vous avez choisi les bonnes fonctions PHP pour rendre vos données un peu plus sûres. C'est très bien. Votre erreur est dans l' ordre des opérations , et comment et où utiliser ces fonctions.
Il est important de comprendre la différence entre le nettoyage et la validation des données utilisateur, l'échappement des données pour le stockage et l'échappement des données pour la présentation.
Désinfection et validation des données utilisateur
Lorsque les utilisateurs soumettent des données, vous devez vous assurer qu'ils ont fourni ce que vous attendez.
Désinfection et filtrage
Par exemple, si vous attendez un nombre, assurez-vous que les données soumises sont un nombre . Vous pouvez également convertir des données utilisateur dans d'autres types. Tout ce qui est soumis est initialement traité comme une chaîne, donc forcer les données numériques connues à être un entier ou un flottant rend le nettoyage rapide et indolore.
Qu'en est-il des champs de texte et des zones de texte de forme libre? Vous devez vous assurer qu'il n'y a rien d'inattendu dans ces domaines. Principalement, vous devez vous assurer que les champs qui ne devraient pas avoir de contenu HTML ne contiennent pas réellement de HTML. Il existe deux manières de résoudre ce problème.
Tout d'abord, vous pouvez essayer d' échapper à l' entrée HTML avec htmlspecialchars
. Vous ne devez pas utiliser htmlentities
pour neutraliser le HTML, car il effectuera également le codage des caractères accentués et autres qui, selon lui, doivent également être codés.
Deuxièmement, vous pouvez essayer de supprimer tout HTML possible. strip_tags
est rapide et facile, mais aussi bâclé. HTML Purifier fait un travail beaucoup plus approfondi en supprimant tout le HTML et en permettant une liste blanche sélective de balises et d'attributs.
Les versions PHP modernes sont livrées avec l'extension de filtre , qui fournit un moyen complet de nettoyer les entrées utilisateur.
Validation
S'assurer que les données soumises sont exemptes de contenu inattendu ne représente que la moitié du travail. Vous devez également essayer de vous assurer que les données soumises contiennent des valeurs avec lesquelles vous pouvez réellement travailler.
Si vous attendez un nombre entre 1 et 10, vous devez vérifier cette valeur. Si vous utilisez l'une de ces nouvelles entrées numériques sophistiquées de l'ère HTML5 avec un spinner et des étapes, assurez-vous que les données soumises correspondent à l'étape.
Si ces données proviennent de ce qui devrait être un menu déroulant, assurez-vous que la valeur soumise est celle qui apparaît dans le menu.
Qu'en est-il des entrées de texte qui répondent à d'autres besoins? Par exemple, les entrées de date doivent être validées via strtotime
la classe DateTime ou . La date donnée doit être comprise entre les plages attendues. Qu'en est-il des adresses e-mail? L' extension de filtre mentionnée précédemment peut vérifier qu'une adresse est bien formée, bien que je sois fan de la bibliothèque is_email .
La même chose est vraie pour tous les autres contrôles de formulaire. Vous avez des boutons radio? Validez par rapport à la liste. Avez-vous des cases à cocher? Validez par rapport à la liste. Vous avez un téléchargement de fichier? Assurez-vous que le fichier est d'un type attendu et traitez le nom de fichier comme des données utilisateur non filtrées.
Chaque navigateur moderne est livré avec un ensemble complet d'outils de développement intégrés, ce qui rend facile pour quiconque de manipuler votre formulaire. Votre code doit supposer que l'utilisateur a complètement supprimé toutes les restrictions côté client sur le contenu du formulaire !
Échapper aux données pour le stockage
Maintenant que vous vous êtes assuré que vos données sont au format attendu et ne contiennent que les valeurs attendues, vous devez vous soucier de la conservation de ces données dans le stockage.
Chaque mécanisme de stockage de données a une manière spécifique de s'assurer que les données sont correctement échappées et codées. Si vous créez du SQL, le moyen accepté de transmettre des données dans les requêtes consiste à utiliser des instructions préparées avec des espaces réservés .
L' extension PDO est l'un des meilleurs moyens de travailler avec la plupart des bases de données SQL en PHP . Il suit le modèle courant de préparation d'une instruction , de liaison de variables à l'instruction , puis d' envoi de l'instruction et des variables au serveur . Si vous n'avez jamais travaillé avec PDO, voici un très bon tutoriel orienté MySQL .
Certaines bases de données SQL ont leurs propres extensions spécialisées en PHP, notamment SQL Server , PostgreSQL et SQLite 3 . Chacune de ces extensions a préparé un support d'instructions qui fonctionne de la même manière préparer-lier-exécuter que PDO. Parfois, vous devrez peut-être utiliser ces extensions au lieu de PDO pour prendre en charge des fonctionnalités ou un comportement non standard.
MySQL a également ses propres extensions PHP. Deux d'entre eux, en fait. Vous ne voulez jamais utiliser que celui appelé mysqli . L'ancienne extension "mysql" est obsolète et n'est ni sûre ni sensée à utiliser à l'ère moderne.
Personnellement, je ne suis pas fan de mysqli. La manière dont il effectue la liaison de variables sur les instructions préparées est inflexible et peut être pénible à utiliser. En cas de doute, utilisez plutôt PDO.
Si vous n'utilisez pas de base de données SQL pour stocker vos données, consultez la documentation de l'interface de base de données que vous utilisez pour déterminer comment transmettre les données en toute sécurité.
Lorsque cela est possible, assurez-vous que votre base de données stocke vos données dans un format approprié. Stockez les nombres dans des champs numériques. Stockez les dates dans les champs de date. Stockez de l'argent dans un champ décimal, pas dans un champ à virgule flottante. Consultez la documentation fournie par votre base de données pour savoir comment stocker correctement différents types de données.
Échapper aux données pour la présentation
Chaque fois que vous montrez des données aux utilisateurs, vous devez vous assurer que les données sont échappées en toute sécurité, sauf si vous savez qu'elles ne doivent pas être échappées.
Lorsque vous émettez du HTML, vous devez presque toujours transmettre les données fournies à l'origine par l'utilisateur htmlspecialchars
. En fait, la seule fois où vous ne devriez pas faire cela, c'est lorsque vous savez que l'utilisateur a fourni du code HTML et que vous savez qu'il a déjà été nettoyé à l'aide d'une liste blanche.
Parfois, vous devez générer du Javascript en utilisant PHP. Javascript n'a pas les mêmes règles d'échappement que HTML! Un moyen sûr de fournir des valeurs fournies par l'utilisateur à Javascript via PHP est d'utiliser json_encode
.
Et plus
La validation des données comporte de nombreuses autres nuances.
Par exemple, le codage des jeux de caractères peut être un énorme piège . Votre demande doit suivre les pratiques décrites dans « UTF-8 tout au long ». Des attaques hypothétiques peuvent se produire lorsque vous traitez des données de chaîne comme un jeu de caractères incorrect.
Plus tôt, j'ai mentionné les outils de débogage du navigateur. Ces outils peuvent également être utilisés pour manipuler les données des cookies. Les cookies doivent être traités comme des entrées d'utilisateur non fiables .
La validation et l'échappement des données ne sont qu'un aspect de la sécurité des applications Web. Vous devez vous informer des méthodologies d'attaque des applications Web afin de pouvoir construire des défenses contre elles.