Validation des entrées et injection
Chaque valeur qui arrive de l'extérieur, un champ de formulaire, une chaîne de requête, un en-tête, un fichier envoyé, une URL que vous récupérez, doit être considérée comme hostile tant qu'on n'a pas prouvé le contraire. Il y a injection lorsque cette valeur est traitée comme du code ou une structure au lieu d'une donnée.
Liste de contrôle
- Utilisez toujours des requêtes paramétrées. Ne construisez jamais de SQL par concaténation de chaînes. Utilisez des paramètres liés ou un ORM qui les lie pour vous. Cela écarte l'injection SQL. La même règle s'applique aux NoSQL et aux commandes shell.
- Échappez la sortie selon le contexte. Appuyez-vous sur un moteur de templates ou un framework d'interface qui échappe par défaut (React, par exemple). Soyez très prudent avec toute option de rendu de HTML brut. C'est ainsi que pénètre le cross-site scripting (XSS).
- Validez par liste d'autorisation, pas par liste de refus. Définissez à quoi ressemble une valeur valide et rejetez tout le reste, plutôt que d'essayer de bloquer les entrées malveillantes une par une.
- Protégez les requêtes côté serveur (SSRF). Si le serveur récupère une URL fournie par l'utilisateur, validez-la et bloquez les plages internes ainsi que l'adresse de métadonnées du cloud (169.254.169.254). Utilisez une validation stricte de l'hôte et figez la résolution DNS pour contrer le DNS rebinding.
- Ne désérialisez jamais de données non fiables en code. Évitez pickle, la désérialisation native Java ou PHP et les mécanismes similaires sur des octets contrôlés par un attaquant. Ils exécutent du code.
- Renforcez les envois de fichiers. Vérifiez le contenu réel (octets magiques), et pas seulement l'extension ou le type déclaré. Imposez une taille maximale stricte. Stockez les fichiers hors de la racine web, sous un nom aléatoire ou basé sur un identifiant, jamais sous le nom fourni par l'utilisateur. Servez-les avec le bon type de contenu et
X-Content-Type-Options: nosniff. Analysez-les à la recherche de logiciels malveillants si possible. - Validez les corps de requête avec un schéma. Rejetez les champs inconnus au lieu de les laisser passer (voir mass assignment dans API et requêtes).
Comment tester
- Soumettez
' OR 1=1 --,<script>alert(1)</script>et${7*7}dans chaque champ, et vérifiez qu'ils sont enregistrés et affichés comme du texte littéral. - Pointez chaque champ d'URL vers
http://169.254.169.254/et vershttp://localhost/. - Envoyez un fichier HTML renommé en
.pnget vérifiez qu'il est rejeté ou servi de façon inoffensive.