6
votes

Signes qu'une instruction SQL est dangereuse

Je veux développer une fonction dans PHP qui vérifie la dangereuse d'une instruction SQL. Quand je dis dangereux, je veux dire, certains symboles, caractères ou chaînes utilisées pour obtenir des données d'une base de données que l'utilisateur ne devrait pas voir.

Par exemple:

Sélectionnez * à partir des utilisateurs où userid = '1'

peut être injecté de plusieurs manières. Bien que je nettoie les paramètres, je souhaite également surveiller la sécurité de la requête.

Merci d'avance


3 commentaires

Le terme technique de l'outil est "analyseur statique".


"Quelle est la sécurité de la requête": définir "coffre-fort".


Cette déclaration SQL ne peut pas être injectée du tout. sa juste déclaration SQL. Nous aurions besoin de voir comment cela a été créé.


5 Réponses :


13
votes

Vous essayez de trouver une solution pour un problème qui ne devrait pas exister. Vous devez utiliser des requêtes préparées (précompilées), alors vous n'avez jamais à vous soucier de l'injection SQL et de vous échapper lorsque la requête elle-même est corrigée et que seuls les arguments sont variables.

voir ici pour un exemple sur les utiliser dans PHP: http://mattbango.com/notebook/web-development/prepared-statifs-in-php-and-mysqli/

Un autre avantage est que c'est plus rapide, au moins pour MySQL, car le serveur n'a pas à analyser la requête à chaque fois.


6 commentaires

plus lent, pas plus rapide, sauf si vous n'exécutez réellement la déclaration plusieurs fois par exécution de script.


Les déclarations préparées sont légèrement plus lentes s'il n'est pas exécuté plusieurs fois par page de charge. Cependant, les avantages des déclarations préparées dépassent de loin la micro-optimisation que vous gagnez en ne les utilise pas.


Chris: Cela suppose que vous créez une connexion par page de charge; Dans le cas d'un pool de connexion, vous pouvez préparer les requêtes une fois lorsque la connexion est ouverte.


@wump - es-tu sûr de ça? Outre l'interface SQL aux déclarations préparées, ce qui vous permet de donner à la déclaration un nom comme identifiant, je n'étais pas au courant que c'était possible à Vanilla PHP. Comment obtiendriez-vous une référence à un manipulateur de déclaration afin de l'exécuter?


@chris - J'ai regardé et il ne semble pas que la mise en commun de connexion intégrée de PHP ait un soutien à cela. Je ne suis pas sûr de ce que les frais généraux sont, mais cela semble être une mauvaise chose.


+1 Même si ce n'est pas une vraie question. @chris: Oui, donc si vous avez une requête qui prend 3 heures, il faudra 3 heures et une microseconde lorsqu'il sera utilisé avec une déclaration préparée, OTOH si vous exécutez quelque chose qui prend des milliers de fois de 100 ms, ce sera plus rapide avec le Affirmation préparée. Alors, qu'est-ce qu'il y a à perdre?



1
votes

Ce Article a de bons exemples d'injection SQL et de bonnes explications de l'injection SQL problèmes.


0 commentaires

1
votes

Vous ne «nettoyez» les paramètres. Cela va casser vos données. Pourquoi quelqu'un doit-il appeler "O'Reilly" ne pas être autorisé à entrer son nom dans votre base de données?

Pour mettre n'importe quelle chaîne dans un littéral SQL String, vous devez vous échapper, ou mieux utiliser des déclarations paramétrées afin de ne pas avoir à vous soucier de l'injection SQL. "Assainement" au côté des intrants est la mauvaise approche: elle ajoute des limitations inutiles et ne résout pas le problème total.

Si vous créez une instruction SQL qui a toute chaîne de variable que vous ne vous êtes pas échappé, il est dangereux, période. Que ce soit le plus simple SELECT * ou une charge de jointures et de sous-candidatures massivement compliquées, il ne faut qu'une injection pour vous rendre vulnérable.


1 commentaires

J'ai lié à l'une de vos réponses classiques dans mon post. Je pense que vous le trouverez intéressant.



3
votes

Je conviens que les requêtes paramétrées sont la meilleure façon d'y aller. Toutefois, la plupart des applications PHP / MySQL utilisent MySQL_Query () et la plupart des applications Web sont également vulnérables à une forme d'injection SQL.

SUHOSIN HARDÉ PHP est installé par défaut sur de nombreux systèmes de lampe et dispose d'une fonctionnalité appelée "Heuristics d'injection SQL expérimentaux" , mais cela ne casse pas d'exploits que je connaisse. Une meilleure solution est un pare-feu d'application Web (WAF) qui recherche des attaques telles que l'injection SQL dans le HTTP cru requete. Les GAFS sont requis par les PCI-DSS sont couramment utilisés sur Internet aujourd'hui car ils travaillent.

Il existe une application appelée greensql qui parie sur le fait que les requêtes injectées look différent . Pour la plupart, il s'agit d'un pari sûr, mais un SQL est un langage déclaratif créé gratuitement et il existe de nombreuses façons qu'une attaquante puisse réécrire une requête pour effectuer la même attaque. En bref, ce type de sécubissement arrêtera certaines attaques, mais elle est défectueuse par rapport aux requêtes paramétrisées. Les WAF souffrent du même problème que GreensQL, sa possible d'encoder ou d'obscurcir une attaque de telle sorte qu'il glisse devant la bibliothèque massive d'expressions régulières utilisées pour détecter les attaques. La réponse de Bobince à cette question me fait craquer, son Le point est également vrai pour le processus d'exploitation.


0 commentaires

2
votes

Il y a trois domaines que vous souhaitez vous concentrer sur:

  1. assainir votre contribution. Ce n'est pas des personnages moyens de dépouillement, il signifie définir un acceptable. Whitelist et Rejetting Exceptions
  2. SQL paraméturé utilisateur utilisateur plutôt que de construire un chaîne de syntaxe concatérée et valeurs.
  3. sécuriser la couche de données aussi loin que vous peut en appliquer le principe de moins le privilège et restreindre accès utilisateur public à seulement le Fonctions absolument essentielles, c'est-à-dire ne pas permettre l'accès en écriture à beaucoup de les tables.

    Vous pouvez trouver cela utile: OWASP Top 10 pour les développeurs .NET Partie 1: Injection

    Il est écrit pour .NET Devs, mais les principes transfèrent de manière égale à PHP.


0 commentaires