Est-il vrai que les procédures stockées empêchent les attaques par injection SQL contre les bases de données PostgreSQL? J'ai fait quelques recherches et découvert que SQL Server, Oracle et MySQL ne sont pas sûrs contre l'injection SQL, même si nous n'utilisons que des procédures stockées. Cependant, ce problème n'existe pas dans PostgreSQL.
L'implémentation de procédures stockées dans PostgreSQL Core empêche-t-elle les attaques par injection SQL ou s'agit-il d'autre chose? Ou bien PostgreSQL est-il également sujet à l’injection SQL même si nous n’utilisons que des procédures stockées? Si oui, montrez-moi s'il vous plaît un exemple (par exemple livre, site, papier, etc.).
postgresql
security
sql-injection
Am1rr3zA
la source
la source
Réponses:
Non, les procédures stockées n'empêchent pas l'injection SQL. Voici un exemple réel (à partir d'une application interne créée par une personne créée là où je travaille) d'une procédure stockée qui permet malheureusement l'injection de code SQL:
Ce code de serveur SQL:
à peu près équivalent à postgres:
L'idée du développeur était de créer une procédure de recherche polyvalente, mais le résultat est que la clause WHERE peut contenir tout ce que l'utilisateur souhaite, permettant ainsi une visite à partir de petites tables de Bobby .
Que vous utilisiez des instructions SQL ou des procédures stockées importait peu. L'important est de savoir si votre code SQL utilise des paramètres ou des chaînes concaténées. Les paramètres empêchent l'injection SQL; les chaînes concaténées permettent l'injection SQL.
la source
Les attaques par injection SQL sont celles où des requêtes non approuvées sont directement ajoutées, ce qui permet à l'utilisateur d'exécuter efficacement du code arbitraire, comme l'illustre cette bande dessinée canonique XKCD.
Ainsi, nous obtenons la situation:
Les procédures stockées constituent, en général, de bonnes défenses contre les attaques par injection SQL car les paramètres entrants ne sont jamais analysés.
Dans une procédure stockée, dans la plupart des bases de données (et des programmes), n'oubliez pas que les requêtes précompilées comptent comme des procédures stockées) se présentent comme suit:
Ensuite, lorsque le programme souhaite accéder, il appelle
foo(userInput)
et récupère le résultat avec joie.Une procédure stockée n'est pas une défense magique contre SQL-Injection, car les utilisateurs sont tout à fait capables d'écrire de mauvaises procédures stockées. Cependant, les requêtes pré-compilées, qu'elles soient stockées dans la base de données ou dans le programme, sont beaucoup plus difficiles à percer si vous comprenez le fonctionnement de SQL-Injection.
Vous pouvez en savoir plus sur SQL-Injection:
la source
Oui, dans une certaine mesure.
Les procédures stockées à elles seules n'empêcheront pas l'injection SQL.
Permettez-moi d’abord de citer l’injection SQL d’ OWASP
Vous devez nettoyer les entrées utilisateur et ne pas concaténer les instructions SQL, même si vous utilisez une procédure stockée.
Jeff Attwood a expliqué les conséquences de la concaténation de SQL dans " Donnez-moi le SQL paramétré ou donnez-moi la mort "
Voici le dessin animé intéressant qui me vient à l’esprit chaque fois que j’entends Injection SQL. Je pense que vous avez compris le point :-)
Jetez un coup d’œil à la feuille de triche pour la prévention des injections SQL , les méthodes de prévention sont expliquées en détail ...
la source
La concaténation de chaînes est la cause de l’injection SQL. Ceci est évité en utilisant le paramétrage.
Les procédures stockées ajoutent une couche de sécurité supplémentaire en appliquant une syntaxe non valide lors de la concaténation, mais ne sont pas "plus sûres" si vous utilisez, par exemple, du SQL dynamique.
Donc, votre code ci-dessus est causé par la concaténation de ces chaînes
exec sp_GetUser '
x' AND 1=(SELECT COUNT(*) FROM Client); --
' , '
monkey
'
Cela donne une syntaxe invalide, heureusement
En paramétrant cela donnerait
Ça signifie
@UserName
=x' AND 1=(SELECT COUNT(*) FROM Client); --
@Password
=monkey
Maintenant, dans le code ci-dessus, vous n'obtiendrez aucune ligne car je suppose que vous n'avez pas d'utilisateur
x' AND 1=(SELECT COUNT(*) FROM Client); --
Si le processus stocké ressemblait à ceci (en utilisant du SQL dynamique concaténé ), votre appel de processus stocké paramétré autorisera toujours l'injection SQL.
Ainsi, comme démontré, la concaténation de chaînes est l'ennemi principal de l'injection SQL
Les procédures stockées ajoutent encapsulation, traitement des transactions, autorisations réduites, etc., mais elles peuvent toujours être utilisées de manière abusive pour une injection SQL.
Vous pouvez consulter Stack Overflow pour en savoir plus sur le paramétrage.
la source
« Attaques par injection SQL se produisent lorsque l' entrée utilisateur est mal codé. En règle générale, l'entrée utilisateur est des données que l'utilisateur envoie avec sa requête, les valeurs -à- dire dans les
$_GET
,$_POST
,$_COOKIE
,$_REQUEST
ou des$_SERVER
tableaux. Cependant, l' entrée utilisateur peut également provenir d'une variété d'autres sources, comme les sockets, les sites Web distants, les fichiers, etc. Par conséquent, vous devez vraiment traiter tout sauf les constantes (comme'foobar'
) comme des entrées utilisateur . "Récemment, j'ai étudié de manière approfondie ce sujet et j'aimerais partager avec d'autres du matériel très intéressant, rendant ainsi ce post plus complet et instructif pour tout le monde.
De YouTube
De Wikipedia
De l'OWASP
De PHP Manual
De Microsoft et Oracle
Débordement de pile
Scanner d'injection SQL
la source
Les procédures stockées n'empêchent pas, comme par magie, l'injection SQL, mais elles le facilitent grandement. Tout ce que vous avez à faire est quelque chose comme ceci (exemple Postgres):
C'est ça! Le problème ne se pose que lors de la création d'une requête via la concaténation de chaînes (c-à-d. SQL dynamique), et même dans ces cas, vous pourrez peut-être lier! (Dépend de la base de données.)
Comment éviter l'injection SQL dans votre requête dynamique:
Étape 1) Demandez-vous si vous avez vraiment besoin d’une requête dynamique. Si vous assemblez des chaînes simplement pour définir l'entrée, vous le faites probablement mal. (Il existe des exceptions à cette règle. Une exception concerne la création de requêtes sur certaines bases de données. Vous risquez d'avoir des problèmes de performances si vous ne l'obligez pas à compiler une nouvelle requête à chaque exécution. Mais recherchez ce problème avant de vous lancer. )
Étape 2) Recherchez le moyen approprié de définir la variable pour votre SGBDR particulier. Par exemple, Oracle vous permet d'effectuer les opérations suivantes (en citant leurs documents):
Ici, vous ne concaténez toujours pas l’entrée. Vous vous engagez en toute sécurité! Hourra!
Si votre base de données ne prend pas en charge quelque chose comme ce qui précède (espérons qu'aucun d'entre eux ne l'est encore, mais je ne serais pas surpris) - ou si vous devez toujours concaténer votre entrée (comme dans le cas "parfois" de requêtes de rapports comme J'ai fait allusion à ci-dessus), alors vous devez utiliser une fonction d'échappement appropriée. Ne l'écris pas toi-même. Par exemple, postgres fournit la fonction quote_literal (). Donc vous courriez:
De cette façon, si in_name est quelque chose de sournois comme '[snip] ou 1 = 1' (la partie "ou 1 = 1" signifie que toutes les lignes sont sélectionnées, permettant ainsi à l'utilisateur de voir les salaires qu'il ne devrait pas!), Puis quote_literal enregistre vos fesses par faire la chaîne résultante:
Aucun résultat ne sera trouvé (sauf si vous avez des employés avec des noms vraiment bizarres.)
C'est l'essentiel! Permettez-moi maintenant de vous laisser avec un lien vers un article classique du gourou d'Oracle, Tom Kyte, sur le sujet de l'injection SQL, pour faire passer le message: Linky
la source
quote_ident()
- mais en général, le moyen le plus simple d'écrire du SQL dynamique à l'épreuve des injections consiste à utiliserformat()
et utiliser les espaces réservés%I
pour les identificateurs et les%L
littéraux. De cette façon, le||
quote_....()