CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[PHP] Escape SQL

vava740
vava740
Niveau 10
13 juin 2013 à 15:49:43

Bonjour,

Pour protéger nos requêtes SQL d'éventuelles injections, on utilise en général les requêtes préparées de PDO ou la fonction mysql_real_esacpe_string(). D'après ce que j'ai compris ces fonctions tiennent compte entre autre de l'encodage du serveur SQL pour échapper la chaîne passée en paramètres.

Je ne cherche pas à remettre en question leur utilité, néanmoins j'ai essayé de faire ma propre fonction d'échappement SQL, et je suis arrivé à ce résultat pour le moins simplissime : http://pastebin.com/YFycGR7A

Cette fonction se contente simplement de doubler chaque occurrence du délimiteur de chaîne (par défaut une quote simple), et de même pour le caractère d'échappement (antislash par défaut).

J'imagine que cette fonction est faillible puisqu'ici je ne tiens pas compte de l'encodage ni d'autres paramètres du serveur SQL, néanmoins je me demande sérieusement quel genre de chaîne pourrait être passée à cette fonction pour effectuer une injection SQL malgré l'échappement du délimiteur et du caractère d'échappement.

Actuellement, que faudrait-il faire pour contourner cette fonction d'échappement ? Sur quel type de serveur SQL, versions, etc ?

En gros, en quoi cette fonction est-elle potentiellement faillible ?

Pseudo supprimé
Pseudo supprimé 13 juin 2013 à 16:59:16

https://addons.mozilla.org/fr/firefox/addon/sql-inject-me/eula/148901?src=dp-btn-primary
Essaye par toi-même. :noel:

vava740
vava740
Niveau 10
13 juin 2013 à 17:35:23

Failures: 0
Warnings: 0
Passes: 29240

Je dois en conclure que ma fonction de trois lignes fait le job pour protéger efficacement des injections SQL ? :noel:

vava740
vava740
Niveau 10
13 juin 2013 à 18:37:08

Non mais attends il fait quoi ce plugin en fait ? :hap:
Parce que j'output strictement rien alors je sais pas comment il devine si ça passe ou pas...

Bon en l'occurrence je faisais juste une insertion dans une table de test (et en même temps un append dans un fichier de log pour comparer), il s'avère que tout est passé sans problème, mais y'a légèrement moins de tests que ce à quoi je m'attendais, le plugin a juste testé 15 injections.

http://pastebin.com/8KwQiGQ9

Alors c'est bien mignon, surtout que j'ai retrouvé précisément les mêmes chaînes insérées dans la table (donc tout avait bien été échappé), mais je suis pas sûr que ce soit assez représentatif de la solidité de cette fonction.

Pseudo supprimé
Pseudo supprimé 13 juin 2013 à 18:38:15

http://fr.wikipedia.org/wiki/Injection_SQL
Cette page m'avait été fortement utile.

En gros:
- mysql_esc_rl_string() n'échappe pas que les guillemets doubles/simples mais aussi les caractères spéciaux des requêtes. Wikipédia te donne la liste: (NULL, \x1a, \n , \r , \, ', " et \x00). (exhaustive?)
- faire attention à bien transtyper les nombres, car il ne faut pas nécessairement mettre de guillemets dans la requête.

C'est globalement ce que j'avais retenu, mais j'ai jamais vraiment plongé mon nez à fond dedans. :noel:

vava740
vava740
Niveau 10
13 juin 2013 à 19:05:22

J'ai essayé de passer les caractères en question et ça n'a posé aucun problème, après je sais pas si il faut les mettre dans un ordre particulier, à un emplacement spécial pour faire une injection...

En attendant j'ai trouvé un outil qui a l'air un peu plus sérieux que le plugin Firefox pour tester les injections SQL : https://github.com/sqlmapproject/sqlmap

Il a testé un peu plus de requêtes : http://pastebin.com/PiMG9Nk4

Quoi qu'il en soit j'ai exactement le même nombre de lignes qui ont été insérées en BDD. :fier:

[WARNING] GET parameter 'text' is not injectable
[CRITICAL] all tested parameters appear to be not injectable.

minimoit
minimoit
Niveau 7
14 juin 2013 à 00:10:55

Télécharge et installe Netsparker Community Edition (la version gratuite).

http://www.mavitunasecurity.com/communityedition/

Le logiciel scan et détecte l'ensemble des failles possibles et imaginables qu'un utilisateur avancés pourrait penser exploiter.

Il détaille la faille,indique comment l'exploiter et surtout comment s'en prémunir.Je ne pense pas qu'il existe de logiciels aussi complet et puissant dans l'industrie en ce qui concerne la détection de vulnérabilité.

vava740
vava740
Niveau 10
14 juin 2013 à 09:56:01

Merci minimoit, ce soft m'a l'air pas mal faire ce genre de tests !

Si je cible ma page de test, le logiciel fait 27 tentatives d'injections (j'ai précisé que c'était un serveur MySQL, et de ne pas tester les injections autres que SQL):

http://pastebin.com/KfwZa40q

Aucune injection n'a été faite sur une requête d'insertion (toutes les tentatives se sont retrouvées correctement échappées dans la requête pour être proprement insérées en BDD), et de même sur une requête de sélection (qui m'a remonté les ID des chaînes précédemment insérées).

Je peux en conclure que cette fonction est fiable ?

Fire_Storm
Fire_Storm
Niveau 10
14 juin 2013 à 10:42:13

Attention aux SQLi. On a souvent tendance à ne pas mettre de guillemet autour des nombres et effectivemment ceux ci n'en ont pas forcément beson, cependant ne pas mettre de guillemet signifie qu'on peut donc, si on ne vérifie par le nombre, continuer la requete comme si de rien n'était sans avoir besoin de "fermer" les guillemets.

Résultat des courses une fonction comme mysql_real_escape ne protège plus en rien ce genre d'injection.

Perso je te déconseille d'utiliser tes propres fonctions. Bon logiquement je vois pas comment on peut bypasser une protection comme ça mais je sais qu'il y a des techniques assez avancées se basant sur un mauvais encodage ou un truc du genre qui arrivait à bypasser des fonctions comme addslashes etc. Après j'ai jamais très bien compris comment mais apparemment c'est possible. Et ta fonction est une copie de addslashes.

Bref prudence donc. Exploiter une faille basique n'a rien de compliqué, sauf que dans le domaine tu serais étonné du nombre de possibilités qu'il y a, il suffit que tu aies oublier UNE possibilité pour que toute ta sécurité soit mise en péril.

vava740
vava740
Niveau 10
14 juin 2013 à 11:25:15

Ouais je suis bien d'accord pour les nombres, le but de la fonction ici n'est pas de protéger tout et n'importe quoi dans une requête SQL, c'est vraiment juste pour une chaîne avec un délimiteur spécifique. Pour les nombres c'est clair qu'une vérification ou un cast explicite s'impose.

C'est justement sur les techniques qui jouent sur l'encodage que j'aurais aimé en savoir un peu plus, et apparemment les logiciels que j'ai essayés ne testent pas des failles d'encodage.

Je suis bien d'accord que c'est une mauvaise idée d'utiliser une fonction perso quand il y a déjà des fonctions ou librairies bien plus poussées pour faire ça, néanmoins je suis justement dans un cas où je n'ai aucune fonction ou méthode native me permettant de faire ce que je veux.

Actuellement je développes un DAO perso pour mes projets, permettant d'utiliser au choix PDO, mysqli, mysql_* (ou un peu ce qu'on veut, suffit d'étendre la classe abstraite et d'implémenter les méthodes spécifiques).

J'ai inclus un système de requêtes préparées à la PDO, à la différence qu'en plus de pouvoir affecter une valeur (quote simple), on peut aussi affecter un identifieur (backtick), typiquement pouvoir faire "SELECT :field FROM :table WHERE `id` = :id".

En pratique il y a peu de chances que les identifieurs dynamiques proviennent de l'utilisateur, ce sera plutôt pour un confort de développement à l'intérieur de l'application.

Quoi qu'il en soit ce type d'affectation n'est pas supportée par PDO, mysqli ou mysql_*. PDO propose bien une méthode quote, mais celle-ci utilise une quote simple comme délimiteur (qui est d'ailleurs ajouté autour de la chaîne retournée), et je ne penses pas que ce soit une bonne idée de remplacer le premier/dernier caractère de la chaîne échappée par un backtick pour un identifieur.

Même constat pour la méthode escape_string de mysqli, ou pour un mysql_real_escape_string, ces fonctions n'échappent pas les backtick.

Je suis donc dans un cas où je dois utiliser une fonction perso pour sécuriser l'échappement d'un identifieur, et même si je ne penses pas affecter dynamiquement un identifieur dans une requête SQL tous les jours, c'est une fonctionnalité que je souhaite rendre possible, et sécurisée.

Après on est pas censé mettre tout et n'importe quoi dans un identifieur SQL, contrairement à une valeur, donc je ferais peut-être mieux de tester la valeur avec une expression régulière et lancer une exception à ce moment là plutôt que de déléguer l'identifieur incorrect au serveur SQL qui retournerait une erreur de syntaxe ?

Fire_Storm
Fire_Storm
Niveau 10
14 juin 2013 à 16:15:14

Avec PDO et les requêtes préparées tu n'as plus besoin de te tracasser de savoir si c'est une chaine ou un nombre, je pense que c'est lui qui s'en occupe (je précise bien avec les requêtes préparées).

EN tout cas dans les test que j'ai fait, avec une requête préparées, même sans vérifier que c'est un nombre il m'est impossible d'injecter quoique se soit. Après j'ai quand même ce tic de vouloir faire une vérification xD

vava740
vava740
Niveau 10
14 juin 2013 à 16:29:42

J'ai déjà une couche d'abstraction pour les nombres, donc c'est pas un problème, mais pour les identifieurs dynamiques (noms de colonne, de table,...) t'en penses quoi ?

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Internet
  • Macintosh
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment