web-dev-qa-db-fra.com

Comment vaincre le doublement des apostrophes pour créer une attaque SQLi?

Je sais que certains développeurs doublent les apostrophes pour atténuer SQLi. (C'est quand l'entrée est 'alors ça devient' ')

Y a-t-il un moyen de battre cela?

C'est sur MS SQl Server.

19
DomBat

J'essaie de montrer les deux côtés du spectre de sécurité. La sécurité est importante, vous ne devez donc pas simplement savoir comment vaincre la sécurité, vous devez également savoir comment l'implémenter. Ainsi, je vais d'abord énumérer une prévention. Si vous ne voulez pas lire ceci, faites défiler vers le bas.

Comment puis-je empêcher l'injection SQL?


Doubler les apostrophes est pas la réponse en matière de sécurité, et cela peut conduire à l'insécurité. La réponse dépend du langage de programmation que vous utilisez.

  • Pour SQL Server/Oracle/MySQL
    • Avec Java, utilisez correctement CallableStatements et PreparedStatements.
    • Avec PHP, vous aurez besoin des instructions préparées appropriées.
    • Avec C #/VB.NET, vous aurez besoin de requêtes paramétrées.

Notez que ce sont tous les mêmes concepts dans toutes les langues. Ils ont juste des noms différents.

Même avec des instructions préparées/appelables ou des requêtes paramétrées, ce qui suit est incorrect:

// Bad code, don't use 
string sqlString = "SELECT * FROM [table] WHERE [col] = '"+ something +"' AND [col2] = @Param";

Vous devez jamais concaténer vos variables SQL.

Avec SQL Server, selon la langue de votre choix, votre requête devrait ressembler à ceci:

  • C #

    using (SqlCommand command = new ("SELECT * FROM [tab] WHERE LName = @LName", connection))
    {
        // Add new SqlParameter to the command.
        command.Parameters.Add(new SqlParameter("LName", txtBox.Test));
    
        // Read in the SELECT results.
        SqlDataReader reader = command.ExecuteReader();
        while (reader.Read())
        {
        }
    }
    
  • Java

    Connection con = DriverManager.getConnection("database-connection-string","name","pass");
    
    // Question marks are the bound variables which are parsed in the defined column order. 
    PreparedStatement findLName = con.prepareStatement("SELECT * FROM [tab] WHERE LName = ?");
    
    // The order in which the question marks appear. You can have more than one in a prepared statement. First one is "1", second is "2", and so on.
    findLName.setString(1, Lastname);
    
    findLName.executeQuery();
    
    Statement stmt = con.createStatement();
    
  • PHP

    Consultez w3schools pour un exemple, je ne veux pas que ma réponse soit trop longue.

Notez que cela ne supprime toujours pas l'injection potentielle de scripts sur une page Web. Vous pouvez insérer exactement ce qu'ils demandent, dans des plages acceptables, puis exporter les résultats au format HTML.

S'ils insèrent ce qui suit (exemple simplifié):

<script> window.location.href='hxxp://www.mymalwarewebsite.com/'; </script>

... et vous produisez ce résultat sur votre page, alors vous avez de gros problèmes. Et si vous supprimez quelque chose de <script> à </script>? Et s'ils insèrent:

<scri<script>pt> window.location.href='hxxp://www.mymalwarewebsite.com/'; </scri<script>pt>

...? Si vous supprimez les balises de script avec replace, vous êtes toujours coincé avec cet exploit.

Ce que vous vraiment voulez est le suivant en plus de ce qui précède:

Tais-toi, Mark! Comment puis-je battre en doublant les apostrophes?


  • Vous pourrez peut-être les battre de de différentes manières ; vous pourrez forcer diverses bases de données SQL à traduire unicode en jeu de caractères local. Par exemple, Ā pourrait être converti en A. Encore pire: U+02BC, ou ʼ serait traduit par ', lequel est U+0027. Cela s'appelle Contrebande basée sur Unicode.
  • Bien qu'il ne s'agisse pas vraiment d'une attaque par injection SQL, vous pouvez essayer de forcer le site Web à injecter du code malveillant à afficher à ses utilisateurs. Vous pouvez essayer d'insérer des balises de script (lire ci-dessus pour un exemple). Imaginez que vous injectiez un téléchargement instantané lorsque les gens consultent votre page ou une liste d'utilisateurs.
  • Bien qu'il ne s'agisse pas techniquement d'une attaque par injection SQL, vous pouvez être en mesure de battre cette protection en parcourant la console dans votre navigateur et en vérifiant les nombres entiers envoyés à la base de données, puis modifiez la demande. Cela s'appelle un exploit Direct Object Reference . Il existe différents outils qui peuvent le faire. Les déclarations préparées vous protégeront pas contre cette attaque. Veuillez lire l'article OWASP
38
Mark Buffalo

Y a-t-il un moyen de battre cela?

Peut-être (au moins avec MySQL). Et c'est vraiment simple (vous n'avez pas besoin d'encodages spéciaux ou de l'absence de guillemets, ou quoi que ce soit):

\' [injection] -- -

Ainsi, par exemple, vous avez cette requête:

SELECT FROM table WHERE user = '[INPUT]';

L'entrée est \' [injection] -- -, mais avec ' doublé, il devient: \'' [injection] -- -, ce qui nous amène à cette requête:

SELECT FROM table WHERE user = '\'' [injection] -- -';

La partie injectée sera exécutée comme une requête, car elle n'est plus entre guillemets.

La seule défense appropriée contre l'injection SQL sont les instructions préparées. Ils ne sont pas non plus difficiles à utiliser et donnent souvent un code plus agréable. Il n'y a vraiment aucune bonne excuse pour les défenses artisanales telles que le doublement des devis.

// mise à jour: Il semble que cela ne serait pas possible avec MSSQL. Cela laisserait donc les deux problèmes déjà mentionnés dans les autres réponses: il est toujours vulnérable si aucune citation n'est utilisée dans la requête , ou (éventuellement) pour certains jeux de caractères.

Cela dépend également de la façon dont le doublement a lieu. Si c'est par exemple fait via la base de données , il peut être vulnérable.

14
tim

Cela empêche uniquement les attaques par injection SQL via les paramètres de chaîne. Parfois, le paramètre est un entier (pensez http://www.example.org/?page=3), Alors vous n'avez pas besoin d'apostrophe. Parfois, vous pouvez vérifier si les paramètres sont vulnérables si vous remplacez page=3 Par page=1+2, Par exemple.

7
Volker