web-dev-qa-db-fra.com

Protection par injection SQL de second ordre

Les injections SQL normales ne posent aucun problème car j'utilise toujours des instructions préparées, mais comment se protéger de injections SQL de second ordre ?

26
J. Smith

Une injection SQL de second ordre est une injection où la charge utile est déjà stockée dans la base de données (au lieu d'être livrée dans un paramètre GET). En ce sens, il est quelque peu similaire à XSS stocké (et une injection SQL ordinaire de "premier ordre" serait analogue à XSS réfléchie).

Comment ça marche? Disons que vous laissez les utilisateurs choisir n'importe quel nom d'utilisateur. Ainsi, un attaquant pourrait choisir le nom '; DROP TABLE Users; --. Si vous concaténez naïvement ce nom d'utilisateur dans votre requête SQL pour récupérer des informations sur cet utilisateur, vous avez un problème:

sql = "SELECT * FROM Users WHERE UserName = '" + $username + "'";

Alors, comment gérez-vous cela?

Utilisez toujours des requêtes paramétrées, toujours, toujours, toujours. Traitez toutes les variables comme des données utilisateur non fiables, même si elles proviennent de la base de données. Imaginez simplement que tout est un paramètre GET et agissez en conséquence en les liant en tant que paramètres.

Vous pouvez également filtrer et limiter l'entrée (par exemple, autoriser uniquement les noms d'utilisateur alphanumériques) avant qu'elle ne soit stockée dans la base de données ainsi qu'après sa récupération dans la base de données. Mais je ne compterais pas sur cela comme ma seule ligne de défense, alors utilisez également les requêtes paramétrées.

39
Anders

Il n'y a rien de "spécial" ici. La soi-disant injection SQL de "second ordre" est exactement la même injection SQL, à la différence près que le contenu provient de la base de données plutôt que de données saisies directement par l'utilisateur. Les mêmes règles s'appliquent

  • toujours nettoyer les données d'entrée indépendamment de leur provenance (l'utilisateur, un fichier, une base de données, etc.)

  • N'utilisez jamais la concaténation de chaînes pour créer des commandes exécutables. Utilisez des déclarations préparées, etc.

La règle d'or est de ne jamais faire confiance aux données d'entrée, quelle que soit la sécurité que vous pensez qu'elles peuvent être. Vous ne pouvez pas faire confiance à ce que l'utilisateur peut saisir et vous devez supposer que même vos propres référentiels de données (c'est-à-dire votre base de données) peuvent avoir été compromis d'une manière ou d'une autre ou de `` mauvaises données '' y ont été intégrées. Écrivez votre code en supposant que vous courez dans un environnement hostile, la réalité est que vous êtes.

BTW Je vois que la documentation d'Oracle ne s'est pas améliorée! C'est un texte de présentation très mal rédigé et mal expliqué concernant l'injection de SQl.

1
Tim X