J'étais curieux de savoir s'il était possible de se protéger contre une attaque par injection SQL en supprimant tous les espaces d'une entrée String?
J'ai lu sur SQL Injection à OWASP , mais ils ne mentionnent rien sur la suppression d'espaces, donc j'étais curieux de savoir pourquoi cela le ferait ou non. travail?
Je regardais cette question , qui pose des questions sur trim
, et la première réponse dit ceci:
Non, l'ajout d'une garniture n'empêchera pas l'injection de sql.
trim
ne supprime que l'espace à l'extérieur de votre chaîne.Select * from aTable where name like '%'+@SearchString+'%'
Si vous @SearchString déteniez quelque chose comme
'' update aTable set someColumn='JackedUpValue' where someColumn like '
Ensuite, lorsque vous mettez tout cela ensemble et l'exécutez dynamiquement, vous obtenez
Select * from aTable where name like '%' update aTable set someColumn='JackedUpValue' where someColumn like '%'
Cependant, si vous avez pris cette chaîne de recherche
update aTable set someColumn='JackedUpValue' where someColumn like
et effectué l'opération indiquée dans cette question , n'obtiendrez-vous pas
updateaTablesetsomeColumn='JackedUpValue'wheresomeColumnlike
qui ne devrait pas exécuter, non?
Je suis curieux de savoir s'il existe une forme d'injection SQL qui pourrait vaincre cela? Y a-t-il une seule commande dangereuse de Word? Si cela peut être vaincu, la suppression d'espaces aiderait-elle au moins un peu la défense?
Remarque: Je pose cette question par pure curiosité, pas comme moyen de contourner l'utilisation des méthodes "appropriées" de la prévention des injections SQL.
Non. La suppression d'espaces n'empêcherait pas l'injection SQL, car il existe de nombreuses autres façons de faire en sorte que l'analyseur traite votre entrée. Regardons un exemple. Imaginez que vous ayez une URL qui utilise de manière non sécurisée les entrées fournies par l'utilisateur dans une requête:
http: //example/index.php? id = 1 => SELECT * from page where id = 1
Dans votre exemple, l'attaquant utiliserait des espaces:
http: //example/index.php? id = 1% 20 ou% 201 = 1 => SELECT * from page where id = 1 or 1=1
.
La suppression des espaces réduirait l'injection dans une chaîne.
Imaginons maintenant que l'attaquant ait utilisé une autre forme d'espace blanc, c'est-à-dire des tabulations:
http: //example/index.php? id = 1% 09 ou% 091 = 1 => SELECT * from page where id = 1 or 1=1
.
La suppression des espaces permettrait toujours l'injection.
Selon la technologie utilisée, l'attaquant pourrait remplacer les espaces par /**/
%00
%09
%0a
%0d
ou un nombre quelconque d'unicodes provoquant la tokenisation par l'analyseur SQL. Alors que l'exemple référencé a supprimé plus que des espaces, l'exemple susmentionné tire parti des commentaires SQL pour provoquer la tokenisation qui ne sont pas des espaces. Vous seriez toujours vulnérable.
Le seul moyen fiable d'empêcher l'injection SQL est d'utiliser des requêtes paramétrées.
Nous sommes en 2016! Les injections SQL appartiennent au passé, sauf si vous utilisez du code non sécurisé.
Quelle que soit la langue que vous utilisez, si vous souhaitez empêcher tout et tous injections SQL, utilisez des instructions préparées ou tout autre type de données contraignant.
Les instructions préparées séparent la requête des données, ce qui empêche les données d'affecter la requête.
Pour répondre directement à votre question, la suppression d'espaces réduirait les injections SQL (lors de l'utilisation de code et de bibliothèques obsolètes), mais limiterait sûrement votre texte d'entrée (aucun espace nulle part).
Cela limiterait le problème, mais ne l'éliminerait pas. Considérez la situation suivante:
$un = str_replace(" ", "", $_POST["username"]);
$pw = hash($_POST["password"];
$sql = "SELECT * FROM users WHERE username = '$un' AND password = '$pw'";
Disons que je poste le nom d'utilisateur admin'--
. Cela me connecterait en tant qu'administrateur, sans utiliser un seul espace.
Comme le souligne wireghoul , vous devrez également supprimer d'autres caractères vides comme tab. Mais comme le souligne Julie Pelletier , utilisez simplement des instructions préparées. Essayer de trouver des schémas intelligents pour arrêter SQLi sans cela pourrait être un jeu amusant, mais cela ne vous donnera jamais la sécurité que les instructions préparées offrent. Tout le reste n'est qu'une distraction.
Non. Disons que vous avez ceci comme SQL:
"select * from people where last_name = '" + surname + "'"
Si j'entre: 'OR(1=1)OR'a'='
dans l'entrée, cela se transforme en:
select * from people where last_name = ''OR(1=1)OR'a'=''
Qui s'exécute dans Oracle et MySQL (au moins) et renvoie toutes les lignes de la table.
Cependant, si vous avez pris cette chaîne de recherche
update aTable set someColumn='JackedUpValue' where someColumn like
Et effectué l'opération indiquée dans cette question, n'obtiendrez-vous pas
updateaTablesetsomeColumn='JackedUpValue'wheresomeColumnlike
Qui ne devrait pas s'exécuter, non?
Comme d'autres l'ont souligné, il existe d'autres façons d'intégrer des espaces dans diverses implémentations de base de données SQL dont vous auriez besoin pour prendre en compte, comme les onglets et \n
(Nouvelle ligne). Presque tous les moteurs de bases de données accepteraient volontiers:
update
aTable
set
someColumn='JackedUpValue'
Il peut y avoir divers caractères Unicode qui fonctionnent comme des espaces en fonction des paramètres de localisation dans diverses bases de données, mais vous devrez vraiment fouiller dans les détails de l'implémentation pour le comprendre. Il n'y a vraiment aucune raison d'essayer de couvrir tous ces cas Edge pour le remplacement de chaîne par rapport à l'utilisation de requêtes paramétrées.
Voici donc une idée. Les serveurs de base de données prennent la requête SQL entrante et l'exécutent via un analyseur, ce qui donne une arborescence d'analyse. Ensuite, ils transforment l'arbre en plan et exécutent le plan.
L'essence de l'injection est que l'analyseur produit un arbre différent de celui prévu par le programmeur.
Le correctif est donc de pouvoir détecter des arbres d'analyse inhabituels. Parcourez l'arbre après l'analyse et produisez une chaîne sous forme canonique moins les valeurs des données. Calculez un SHA hachage de la chaîne. Gardez une table des hachages connus pour l'utilisateur de l'application/base de données. Avertissez ou abandonnez si le serveur voit un hachage inconnu.
Évidemment, il y a un problème de démarrage. Le programmeur devrait donc exécuter l'application en mode test, extraire les hachages après des tests exhaustifs et charger le serveur avec les hachages au démarrage de l'application. Activez ensuite abort-on-new-hash et aucune injection SQL supplémentaire ne devrait être possible.