web-dev-qa-db-fra.com

Y a-t-il une longueur de champ trop courte pour permettre une injection SQL nuisible?

Je lisais sur l'injection SQL et je l'ai vu, ce qui m'a fait penser:

des champs d'entrée aussi petits que possible pour réduire la probabilité qu'un pirate informatique puisse insérer du code SQL dans le champ sans qu'il soit tronqué (ce qui entraîne généralement une erreur de syntaxe T-SQL).

Source: Microsoft SQL Server 2008 R2 Unleashed

Quelle est la taille de champ la plus courte où l'injection SQL peut être nuisible?

Le préjudice étant la modification de la base de données ou le renvoi de résultats non prévus par la conception. Inclure un marqueur de commentaire de fin (--) dans un champ à deux caractères ne causerait pas de dommages, cela entraînerait simplement l'échec d'une requête. Le pirate informatique potentiel pourrait apprendre que le terrain est susceptible d'être injecté, mais il n'est pas en mesure d'en tirer parti.

51
James Jenkins

Non, aucune longueur n'est trop courte pour être exploitable (du moins dans certaines situations).

Un filtre de longueur n'est pas une protection valide contre l'injection SQL, et les instructions préparées sont vraiment la seule défense appropriée.

Un filtre de longueur est cependant une bonne mesure comme défense en profondeur (comme le sont les filtres entiers, les filtres alphanum, etc.). Il existe de nombreuses situations où, par exemple une entrée valide ne peut jamais dépasser 30 caractères, mais là où une exploitation significative nécessite plus. Il va sans dire (mais probablement pas) que tout filtrage comme défense en profondeur doit avoir lieu côté serveur car tout ce qui est côté client peut simplement être contourné.

Contournement de restriction

Les clauses de restriction (par exemple AND/OR) peuvent être contournées par deux caractères, ce qui peut causer un préjudice réel, pas seulement une requête ayant échoué. L'exemple le plus simple est une connexion (d'autres exemples seraient la suppression non autorisée de données supplémentaires):

SELECT * FROM users WHERE userid = [id] AND password = [password]

Injection:

id = 1#
password = wrong_password

Charge utile: 2 caractères

DoS

Les attaques DoS nécessitent très peu de caractères. Dans un exemple MySQL, il faut 7 pour l'appel réel + x pour les secondes données + tout ce qui est nécessaire pour pouvoir appeler la fonction et corriger la requête.

Exemple:

SELECT * FROM users WHERE userid = [id]

Injection (c'est une injection valide, une forme plus longue serait 1 AND sleep(99)):

sleep(99)

Charge utile: 9 caractères

Lecture des données

Si les données sont affichées, la longueur dépend principalement du nom de la table et de la colonne. Je suppose que le nombre de colonnes est égal pour toutes les tables (cela peut arriver et cela enregistre les caractères).

Exemple:

SELECT * FROM comments WHERE commentid = [id]

Injection:

1 union select * from users

Charge utile: 27 caractères.

Modification des données

Des modifications non autorisées de la base de données peuvent également être réalisées avec peu de caractères.

Exemple:

UPDATE users SET password = '[password]' WHERE id = [id]

Injection (dans le mot de passe):

',isadmin='1

Charge utile: 12 caractères

Un contournement de restriction fonctionnerait également (le résultat est que tous les mots de passe sont maintenant vides *):

'#

Charge utile: 2 caractères

* L'exemple de mot de passe est utilisé pour plus de simplicité; les mots de passe doivent être hachés, ce qui rend l'exemple impossible. L'exemple s'applique toujours dans toutes les situations similaires (mise à jour d'un nom d'utilisateur, mise à jour des autorisations, etc.)

86
tim

Sans contexte, je vais supposer que l'auteur fait référence à des champs de saisie dans une application cliente. L'exemple le plus simple à utiliser serait un formulaire dans une page HTML dans une application Web, bien que ce que je vais décrire est efficace pour pratiquement n'importe quel type d'application client.

Dans ce contexte, la réponse est non, il n'y a pas de longueur maximale de champ d'entrée suffisamment courte pour vous protéger contre l'injection SQL, car vous ne contrôlez pas la longueur maximale de champ d'entrée. L'attaquant le fait. Lorsque le formulaire contenant le champ de saisie réside sur le client (comme dans une fenêtre de navigateur sur la machine de l'attaquant), il est en dehors de la limite de confiance et hors de votre contrôle. Il peut être manipulé de la manière souhaitée ou nécessaire par l'attaquant, ou évité complètement. N'oubliez pas que pour une application Web, tout ce que vous obtenez est une requête HTTP. Vous n'avez aucune idée de la façon dont il a été créé, et aucune raison de croire que tout ce que vous avez demandé au navigateur de faire s'est réellement produit, que des contrôles de sécurité côté client ont effectivement été exécutés, que n'importe quoi dans la demande est aussi vous vouliez ou en toute sécurité.

Donc non, la longueur du champ d'entrée n'est pas un mécanisme de prévention d'injection SQL valide, et ne faites jamais confiance à une entrée qui franchit une limite de sécurité sans la valider.

90
Xander

des champs d'entrée aussi petits que possible pour réduire la probabilité qu'un pirate informatique puisse insérer du code SQL dans le champ sans qu'il soit tronqué (ce qui entraîne généralement une erreur de syntaxe T-SQL).

À mon humble avis, c'est juste de la merde. Utiliser la longueur des champs de saisie pour se protéger de l'injection SQL est un mauvais conseil:

  • La seule façon correcte de se protéger de l'injection SQL est d'utiliser une instruction préparée. Les données d'entrée sont un paramètre de la requête et ne seront jamais utilisées comme texte SQL.
  • La taille d'un champ doit être contrôlée côté serveur car vous ne pouvez jamais faire confiance à ce qui vient dans une demande - elle peut être fausse - et doit être utilisée pour nettoyer les données avant leur utilisation dans la couche de gestion ou le stockage de la base de données.
  • Les conseils pour utiliser autre chose que les meilleures pratiques prêtent à confusion pour les développeurs débutants.
11
Serge Ballesta

Non.

Considérez la requête:

select * from tweets
WHERE RowNum >= [offset]
AND RowNum < [offset] + [limit]

Si vous pouviez injecter un seul non entier (par exemple, la lettre "a") pour offset, la requête entraînerait une erreur de syntaxe et aucun message ne s'afficherait produisant vos "résultats non prévus par la conception". exigence de causer des dommages. Si vous pouvez injecter une chaîne vide, vous obtenez le même effet avec une charge utile de longueur nulle. Injecter un commentaire de fin serait un gaspillage de deux caractères;)

Un attaquant peut en tirer parti dans une attaque par déni de service (différemment d'une inondation du résea généralement associée au DoS, mais toujours un DoS ). Selon le service refusé, cela pourrait être catastrophique.

Comme d'autres réponses le suggèrent, la longueur du champ n'a aucune incidence sur l'impact de l'injection SQL. Les instructions préparées et paramétrées sont la voie à suivre, comme indiqué dans le OWASP SQL Injection Prevention Cheat Sheet .

8
benrifkah

Non.

Exemple simple d'une injection SQL à un caractère:

`

Cela générerait une erreur qui serait un exemple de "retour de résultats non prévus par la conception". Plusieurs fois, les erreurs peuvent être utilisées pour obtenir des informations qui aideront plus tard dans un exploit.

4
MikeSchem

Oui.

La longueur maximale est nulle. La seule façon de sécuriser une entrée non fiable via une longueur maximale, sans autre validation ou vérification, est de ne pas tenir compte de l'entrée à partir de l'index 0.

Il existe de nombreuses autres (meilleures) réponses ici, mais celle-ci sert à répondre à la question théorique de savoir comment rester en sécurité lorsque la longueur du champ est le seul outil à votre disposition.

3
Dan

La longueur d'un champ n'aura rien à voir avec l'injection SQL, car une telle attaque fonctionne en commentant simplement le code précédent et en démarrant le code d'attaque, de sorte que la longueur d'un champ n'affectera pas cette stratégie.

0
Spencer Williams

Il y a beaucoup de théorie ici mais pas d'exemples réels. Lorsque j'ai trouvé une vulnérabilité d'injection SQL dans le monde réel (maintenant corrigée), j'ai essayé d'utiliser des champs de saisie d'environ 30 caractères. C'était très frustrant car il m'a fallu un certain temps pour comprendre que tout après 30 caractères avait été abandonné, et 30 caractères ne me laissaient pas beaucoup de place.

(beaucoup d'exemples d'injection sql ont simple sql "comme select * dans la table où id = @id", sql du monde réel sera généralement beaucoup plus compliqué)

Vous pouvez avoir de la fantaisie avec votre entrée, et un expert SQL pourrait probablement utiliser quelques astuces pour réduire le nombre de charges utiles. Mais peu importe à quel point vous êtes difficile si vous souhaitez sélectionner un nom de table long, vous aurez besoin de beaucoup de caractères pour cela.

Quoi qu'il en soit, lorsque je suis passé à l'utilisation d'un champ de saisie avec plus de 1 000 caractères, j'ai trouvé que beaucoup pour l'injection SQL.

Cela étant dit, comme de nombreux commentateurs au-dessus de moi l'ont dit, La meilleure défense contre l'injection SQL est des déclarations préparées

0
Almenon