web-dev-qa-db-fra.com

Quelques doutes sur les exemples d'injection SQL, comment fonctionne exactement?

Je suis un développeur de logiciels qui commence à étudier la sécurité des applications et j'ai le doute suivant concernant l'injection SQL.

Je suis un cours vidéo et il y a ces deux exemples:

  1. J'ai une requête SQL non sécurisée comme celle-ci:

    txtSql = "SELECT * FROM Users WHERE UserId = " + txtUserId
    

    Si la valeur transmise de txtUserId est quelque chose comme 99 OR 1 = 1, J'obtiendrai une requête comme celle-ci

    SELECT * FROM Users WHERE UserId = 99 OR 1 = 1
    

    qui me renverra la liste complète des enregistrements contenus dans la table Users car 1 = 1 est toujours vrai et la concaténation OR retournera vrai donc c'est comme cette requête:

    SELECT * FROM Users WHERE TRUE
    

    me renvoyant la liste complète des enregistrements. Ce raisonnement est-il correct?

  2. Ensuite, j'ai ce deuxième exemple plus sophistiqué:

    Il existe un formulaire de connexion utilisateur (nom d'utilisateur et mot de passe). Derrière ce formulaire, il y a cette implémentation de requête non sécurisée:

    sql = 'SELECT * FROM USERS WHERE Name = "' + uName + '" AND Pass = "' + uPass + '"'
    

    Si l'utilisateur insère les données suivantes dans le formulaire de connexion:

    uName = " OR ""="
    uPass = " OR ""="
    

    La requête de résultat sera:

    SELECT * FROM Users WHERE Name = "" OR ""="" AND Pass = "" OR ""=""
    

    Il s'agit donc de sélectionner des enregistrements où

    • Le champ Name est vide ("") ou égal à "=" (et cette condition doit toujours être fausse car il est assez étrange d'avoir un nom d'utilisateur vide ou un nom d'utilisateur comme "=").

    • Le champ Pass est vide ("") ou égal à "=" (et cette condition doit toujours être fausse car il est assez étrange d'avoir un mot de passe vide ou un mot de passe comme "=").

    Nous avons donc un conditionnel comme:

    WHERE FALSE AND FALSE
    

    Et voici mon doute: FALSE AND FALSE = FALSE

Pourquoi est-il dit que cette requête me renvoie la liste complète des enregistrements de la table utilisateur?

Si j'ai bien compris la logique, la deuxième requête devrait se traduire par quelque chose comme ceci:

SELECT * FROM Users WHERE FALSE AND FALSE

Quel est le problème dans mon raisonnement? Qu'est-ce que je rate?

8
AndreaNobili

Vous avez mal lu l'injection, en particulier cette partie:

""=""

Ce n'est pas de vérifier si le Name est un signe égal, mais plutôt si une chaîne vide est égale à une chaîne vide. C'est en fait la même chose que 1=1 (et ils auraient pu utiliser 1=1 tout aussi bien ici), et est donc l'équivalent de TRUE. Donc, cette clause:

Name = "" OR ""=""

Est le même que Name="" OR 1=1 aussi bien que Name="" OR TRUE

Il est facile de mal lire quelque chose comme ça. Je suis sûr que c'est tout ce dont vous avez besoin, car sinon vous comprenez clairement ces concepts! Mais pour être un pédant, la requête se résume essentiellement à:

WHERE Name="" OR TRUE AND Pass="" OR TRUE

Ce qui se passera ensuite pourrait dépendre de l'ordre de priorité exact, mais ce sera probablement parfait. Une autre astuce que vous pourriez utiliser serait de terminer le nom d'utilisateur avec une barre oblique inverse supprimer Pass de la requête tous ensemble (bien que cela puisse ne pas fonctionner dans toutes les versions de SQL). Imaginez injecter User=\ et Pass= OR 1=1 -- (se termine par un commentaire). Vous vous retrouverez avec cette requête:

SELECT * FROM USERS WHERE Name="\" AND Pass = " OR 1=1 --"

En raison de la barre oblique inverse, il recherchera un Name de " AND Pass = (qui ne correspondra à rien), mais alors le OR 1=1 le fera correspondre à tout. Le commentaire de fin supprime la dernière citation double qui provoquerait sinon une erreur de syntaxe. Ce formulaire vous donne un peu plus de contrôle sur la requête en nuançant efficacement la recherche dans la colonne Pass et en abandonnant ainsi toutes les clauses AND/OR. Par exemple, vous pouvez rechercher un ID réel en remplaçant votre condition Pass par OR ID=10 (en supposant qu'il existe une colonne ID).

7
Conor Mancone