2010-06-01 19 views
5

Cela pourrait être une question stupide. Ou peut-être que mes capacités de piratage sont limitées (je ne les pratique pas du tout).Les requêtes multilignes sql-injection sont-elles sécurisées?

J'ai une requête qui ressemble à ceci:

<?php 
$query =<<<eot 
    SELECT  table_x.field1, 
       table_x.field2, 
       table_y.*, 
       table_z.field4 
    FROM  (
        SELECT ... 
       ) as table_y 
    LEFT JOIN table_x 
    ON   table_x.field1 = table_y.field_x 
    LEFT JOIN table_z 
    ON   table_z.field1 = table_y.field_z 
    WHERE  table_x.field3 = '$something' 
    AND   table_z.field4 = '1' 
    AND   table_z.field5 = '2' 
eot; 
?> 

J'ai beaucoup d'autres tests sur $something avant qu'il ne soit utilisé, comme $something = explode(' ',$something); (ce qui entraîne plus tard dans une chaîne) aucun d'entre eux l'intention d'empêcher injection, mais ils rendent difficile pour l'injection donnée d'obtenir ce qui est à la requête réelle. Cependant, il existe des moyens. Nous savons tous combien il est facile de remplacer un espace pour autre chose qui est toujours valide ..

Donc, ce n'est pas vraiment un problème de faire un tronçon SQL potentiellement dangereux que $something ... Mais y a-t-il façon de commenter le reste de la chaîne de requête d'origine si elle est multi-ligne?

Je peux commenter AND table_z.field4 = '1' en utilisant ;-- mais ne peut pas commenter les éléments suivants AND table_z.field5 = '2'

Est-il possible d'ouvrir un commentaire sur plusieurs lignes /* sans la fermer ou quelque chose qui ressemblait, et donc permettre l'injection d'ignorer la multi requête de ligne?

Répondre

4

Ce n'est pas sûr. Même s'il ne peut pas commenter le reste, il pourrait le préfixer avec SELECT * FROM my_table WHERE 1 = 1.

+0

Merci Adam, vous avez raison. Il est facile de pirater cette requête multi-ligne. Honte à moi de ne pas avoir vu cette option. Ceci est cependant un exemple et ma situation est un peu plus compliquée. Puisque j'ai échoué à m'expliquer, j'accepterai votre réponse comme correcte. – acm

5
$something = "'; DROP TABLE table_x; SELECT * FROM table_z WHERE '1' = '1"; 
2

Utilisez préparé des déclarations pour être sûr:

http://www.php.net/manual/en/pdo.prepare.php

interpolation de chaîne a toujours le risque d'injection de code si votre entrée est pas suffisamment nettoyée. La suppression de la possibilité d'exécuter du code arbitraire est la méthode la plus simple et la plus sûre.

+0

+1 C'est vraiment la seule bonne réponse. "Nettoyer" vous-même est aussi bon que votre connaissance de l'injection SQL. Laissez la base de données/testée ORM la gérer pour vous. – richsage

2

@Techpriester: ce n'est pas ce qu'une instruction préparée est.

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html (ancienne version, la même chose)

AOP est une couche d'abstraction de base de données « prépare des déclarations », mais une déclaration préparée est tout autre chose!

+1

PDO émule les instructions préparées par défaut, mais vous pouvez désactiver ce mode sur $ pdo-> setAttribute (PDO :: ATTR_EMULATE_PREPARES, false); 'Regardez votre journal de requêtes MySQL général et voyez-le fonctionner! –