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.
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.
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.
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:
HtmlEncode
Java Html Sanitizer from OWASP
HtmlEntities
.Ā
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. 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.
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.