sécuriser les injections SQL

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par sigma2008, 20 Novembre 2014.

  1. sigma2008
    sigma2008 WRInaute impliqué
    Inscrit:
    18 Juin 2008
    Messages:
    790
    J'aime reçus:
    5
    Bonjour,
    Je créé un formulaire de connexion et d'inscription, tout va bien, maintenant je veux éviter les injections SQL, j'ai lus plein d'article et je souhaite confirmer :)

    Dans mon formulaire de connexion j'ai ajouté mysql_real_escape_string() pour éviter l'injection sur SELECT :
    Code:
    $email=mysql_real_escape_string($_POST['mail']);
    $password=mysql_real_escape_string($_POST['password']);
    .............
    ....SELECT * from users where email =$email and password=$password ......
    
    donc là tout est OK select est sécurisée, il reste le formulaire d'inscription, quand je récupère les variables post mail et post password dois je faire la même chose ? C'est à dire mysql_real_escape_string() avant de les insérer ? (insert into ...)

    Merci
     
  2. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 169
    J'aime reçus:
    346
  3. Blount
    Blount WRInaute impliqué
    Inscrit:
    18 Novembre 2010
    Messages:
    701
    J'aime reçus:
    0
    Toutes les données provenant du navigateur sont potentiellement un danger.
    Donc, à partir du moment où tu vas insérer une donnée en BDD, tu protèges. Que ce soit pour les $_GET et les $_POST mais aussi les $_COOKIES et les données extérieurs.

    En règle général, peu importe d'où proviennent les données, s'il s'agit d'une chaîne de caractères, il faut appliquer un mysql_real_escape_string ne serait-ce que pour échapper les caractères ' et ".

    Si c'est censé être une valeur numérique, alors tu peux caster la variable: (int) $var ou (float) $var.
     
  4. frenchhorn
    frenchhorn WRInaute passionné
    Inscrit:
    8 Février 2007
    Messages:
    1 136
    J'aime reçus:
    3
    regarde du côté des requêtes préparée et PDO
     
  5. noren
    noren WRInaute accro
    Inscrit:
    8 Avril 2011
    Messages:
    2 816
    J'aime reçus:
    18
    Tout comme frenchhorn, je pense que l'idéal c’est également les requêtes préparées. Pour double sécurité tu peux également faire un contrôle de chaque champ saisi pour voir si ils sont conformes à ce que tu attends.
     
  6. sigma2008
    sigma2008 WRInaute impliqué
    Inscrit:
    18 Juin 2008
    Messages:
    790
    J'aime reçus:
    5
    Merci pour vos réponses, et pour les $_SESSION dois je à chaque fois avant l'insertion dans la bdd ajouter mysql_real_escape_string ? a savoir que les données de sessions sont de provenance bdd et non pas d'un formulaire ou autre.
     
  7. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 169
    J'aime reçus:
    346
    Tu peux échapper toutes les données.
    Si ça te fait peur, regarde du côté de PDO comme te l'a suggéré frenchhorn.
     
  8. baud74
    baud74 WRInaute impliqué
    Inscrit:
    21 Juillet 2014
    Messages:
    580
    J'aime reçus:
    0
    sauf erreur, en faisant :
    SELECT * from users where email ='$email' and password='$password'
    et avec la bonne valeur pour la variable qui va bien, le ' est transformé en \', donc il n'y plus de possibilité de faire une requête sql dangeureuse et valide.
     
  9. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 169
    J'aime reçus:
    346
    Uniquement avec les magic quotes à On (evil).
    Si: $password = $_POST['password'];

    Alors: on px faire une injection:
    Code:
    ' OR 1=1/*
     
  10. Leonick
    Leonick WRInaute accro
    Inscrit:
    8 Août 2004
    Messages:
    19 274
    J'aime reçus:
    0
    tout dépend de ce que tu as laissé mettre dans ton $_SESSION. Si ce sont des données en provenance de l'extérieur et non traitées avant leur affectation, il faut les traiter avant une quelconque utilisation en bdd
     
  11. frenchhorn
    frenchhorn WRInaute passionné
    Inscrit:
    8 Février 2007
    Messages:
    1 136
    J'aime reçus:
    3
    exact, il faut préparer chaque data que tu insert dans ta base de donnée
     
  12. noren
    noren WRInaute accro
    Inscrit:
    8 Avril 2011
    Messages:
    2 816
    J'aime reçus:
    18
    De toute façon mysql_real_escape_string est obsolète

    il faut au moins passer par mysqli_real_escape_string

    Et comme indiqué le mieux reste malgré tout les requêtes préparées et éventuellement combiné avec un contrôle des champs saisis en amont. Si tu attend par exemple une valeur numérique, un petit test is_numeric() ne fera pas de mal.

    Les requêtes préparées peuvent être utilisées avec mysqli si tu ne souhaite pas utiliser pdo :

    http://php.net/manual/fr/mysqli.quickstart.prepared-statements.php
     
  13. zeb
    zeb WRInaute accro
    Inscrit:
    5 Décembre 2004
    Messages:
    12 021
    J'aime reçus:
    1
    Non faut caster et pas réfléchir c'est plus rapide et moins gourmand ... (penser a prévoir le cas par défaut aussi quand on caste)
     
  14. noren
    noren WRInaute accro
    Inscrit:
    8 Avril 2011
    Messages:
    2 816
    J'aime reçus:
    18
    Je n'aime pas trop l'idée du caste. En fin de compte tu fais quand même une ou plusieurs actions (update, insert...) alors qu'il y a quoi qu'il en soit un problème dans les données saisies en GET ou POST, par conséquent en faisant de la sorte tu acceptes quand même la requête et peux entrer des valeurs pas forcément bonne ou celles réellement souhaitées à la base par l'internaute.

    Alors qu'avec un is_numeric l'action ne peut pas être effectuée, ce qui me semble plus logique si de mauvaises données sont saisies. Et tu avertis l'internaute avec un message.
     
  15. zeb
    zeb WRInaute accro
    Inscrit:
    5 Décembre 2004
    Messages:
    12 021
    J'aime reçus:
    1
    Mouais pas convaincu, en info on dépense 10 tonnes d'énergie pour un cas qui risque de se produire toutes les lunes ça c'est un vrai souci (10% du code utilise 90% de la CPU ce qui reviens a dire que 90% du code est quasi jamais utilisé).

    Tu n'as qu'a regarder la qualité de l'air de paris pour comprendre que souvent plus simple c'est mieux.

    De toute façon sur du numérique, tu as autant de chances que l'utilisateur se plante de valeur, qu'il n'ajoute un caractère alpha, bref tu ne va rien minimiser tu va juste traiter un cas anecdotique (qui n'aurais pas du se produire à ce stade).

    Si tu dois vérifier que tu as affaire a un entier ou un float c'est côté client qu'il faut le faire pas côté serveur car quand tu en est arrivé là soit c'est bon soit c'est justement une exploitation de faille donc ton test deviens inutile, car il ne faut pas que de l'alpha passe et c'est tout ; si c'était un utilisateur légitime qui avait fait une connerie tu l'aurais prévenu en amont.

    Le code côté serveur il est pas là pour l'utilisateur il est là pour le système, faut distinguer les vérifications normales pour l'utilisation (javascript avec test validité email, fourchette de valeur admissibles, longueur chaines etc ...) et les mesures de protection que tu prend côté serveur pour garantir la validité des données vis a vis de portes que tu n'a pas su voir, à ce stade faut être radical et on en a plu rien a faire de l'utilisateur car si mesure corrective il doit y avoir suite a un oubli de cas possible par l'utilisateur c'est pas dans ce code qu'il faut intervenir mais a la source côté utilisateur.

    Bref tu fait comme tu le sent mais perso je vais pas tester si c'est numérique ou pas ça doit être numérique exclusivement donc je caste point barre. D’où ma remarque attention au cas par défaut qu'il faut prévoir. Je te donne un exemple :

    Souvent dans les formulaire de login on évoque la faille d'injection qui va permettre de se connecter avec un compte. Ce compte est rarement du au hasard c'est souvent le premier de la liste (premier record de la base donc celui qui va être retourné avec une condition ajouté qui renvoie true) Hors souvent c'est un compte admin vu que c'est le premier a être créé ... Le cas défaut dans ce cas du moins la parade c'est d'injecter systématiquement un compte bidon avec droits ultra limité en premier au cas ou tu ai loupé un truc ...
     
  16. noren
    noren WRInaute accro
    Inscrit:
    8 Avril 2011
    Messages:
    2 816
    J'aime reçus:
    18
    Il m'avait toujours semblé qu'il fallait également laisser les tests côté serveurs même si on les effectue déjà côté client (html5, javascript...)

    Je comprend tout à fait ton explication, après au niveau du cout CPU, je n'ai jamais vraiment fait de test pour voir l'impact de telles vérifications. Je serais limite tenter de laisser le is_numeric avec en plus un cast avant l'insertion en BDD (en plus des contrôles côté client). :mrgreen: (paranoïa quand tu nous tiens)

    Après niveau contrôle côté client à part le javascript (qui peut être désactivé) et le HTML5 qui n'est pas encore bien géré au niveau des formulaires sur tous les navigateurs, je ne vois pas comment effectuer un contrôle client sûr. Le plus fiable m'a toujours semblait être côté serveur malgré tout.

    Quoi qu'il en soit merci pour ta remarque, j'en prend note et vais y réfléchir posément, et je vais effectuer quelques tests :wink:
    En tout cas c’est pas bête et peut être qu'un cast sera amplement suffisant

    PS : je ne connaissais pas cette astuce pour le compte utilisateur. En ce qui me concerne même si quelqu'un arrive a se connecter avec mon compte administrateur il ne pourra rien faire :), il faut ensuite qu'il connaisse l'accès à mon backoffice, sinon il sera comme un utilisateur lambda. J'ose également espérer que les requêtes préparées évitent ce type d'injection.

    Mais c’est vraiment chaud d'être "sécure" à 100%. Et dès qu'on manipule des GET/ POST et des espaces membres (sessions...) il faut vraiment être très très prudent.
     
  17. zeb
    zeb WRInaute accro
    Inscrit:
    5 Décembre 2004
    Messages:
    12 021
    J'aime reçus:
    1
    Oui tu as raison il faut l'un et l'autre mais tu peux exporter la vérification de format côté client (traiter les cas d'utilisation normal) et te contenter de tests de sécurité côté serveur.

    je met souvent pour pas dire toujours de côté le cas javascript désactivé car c'est souvent (chez moi) tout le site qui est impraticable donc par défaut je considère que javascript est là et sinon pas grave l'utilisateur a qu'a être moins ...
    Donc a priori un utilisateur normal va se faire interpeler si une data est incorrecte niveau format ... après en base c'est une autre histoire là j'impose le format de façon rigide et si il y a un souci c'est soit un "hacker" soit un bug qui sera remonté et corrigé .... Donc dans tous les cas il ne faut pas aveuglément faire confiance a javascript, mais il est possible d'écarter les use case utilisateur légitimes de la procédure de vérification car c'est censé être fait.

    Sinon oui tu as raison gérer des user c'est plus chaud ... mais tellement plus passionnant. Perso j'ai même codé un système de gestion de droits complexe la dedans avec une dizaine de statuts différents et la possibilité d'en ajouter des sur mesure.
     
  18. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 169
    J'aime reçus:
    346
    Quand c'est bien pensé, la validation côté client est générée via les contraintes de validation côté serveur (DRY power).
    The lib pr validation client: http://parsleyjs.org/

    Concernant les failles, on s'en soucie bcp moins quand on utilise un ORM et que les templates sont auto escapés.
     
  19. noren
    noren WRInaute accro
    Inscrit:
    8 Avril 2011
    Messages:
    2 816
    J'aime reçus:
    18
    En parlant de bug remontée et corrigé, j'ai ouvert un topic qui a fait un flop :

    https://www.webrankinfo.com/forum/t/gestion-des-erreurs-mysql-en-production.177223/

    J'en profite donc pour te poser la question. :oops:

    je ne sais pas si tu utilises PDO, mais comment gère tu les erreurs sql en production, laisse tu le mode PDO::ERRMODE_EXCEPTION activé

    ou le met tu en mode SILENT?

    le soucis en le mettant en mode silent, c’est comment être informé des erreurs SQL rencontrées en prod? et si on utilise les transactions comment intercepter une erreur pour faire un rollback? Puisque dans ce cas le try catch (exception ou pdoexception) ne sert plus à rien
     
  20. noren
    noren WRInaute accro
    Inscrit:
    8 Avril 2011
    Messages:
    2 816
    J'aime reçus:
    18
    @spout : Sans forcément parler ORM, les requetes préparées se suffisent ou non?

    Avec une requête du type (c’est une exemple hein) :

    Code:
    select id, login from user where id = ? and pass = ? 
    
    puis un

    Code:
    execute(array($id, $pass)); 
    Dans ce cas on évite les problèmes d'injection non?, et normalement il y a dans cette requête automatiquement un contrôle et une gestion du typage non?

    Si l'id n'est pas numerique pas de risque d'intrusion? Et la requête ne peut pas donner suite. A moins qu'elle fasse également automatiquement un cast (faudrait que je fasse l'essai)

    et si a la place de id = ? , je mettais login = ? idem aucun risque d'injection? les " '--" etc. n'auraient aucun impact?

    Je dois avouer que pour le moment je me suis contenter d'un contrôle sur les champs saisis (dans la mesure du possible), de requêtes préparées et de htmlspecialchars a l'affichage.
    Et pour le vol de session j'utilise :
    session_regenerate_id(true);
    J'oublie certainement encore plein de failles de sécurité. Après j'ai l'avantage de ne pas utiliser un CMS ou framework connu qui sont certainement étudiés à la loupe par les hacker.
     
  21. zeb
    zeb WRInaute accro
    Inscrit:
    5 Décembre 2004
    Messages:
    12 021
    J'aime reçus:
    1
    Non j'utilise pas, le passage msqli est prévu pour cette année après une refonte de design en cours. En tous cas j'ai un opérateur de silence sur toutes les fonctions SQL. J'ai trop chassé les erreurs SQL sur google pour laisser passer les miennes :D
     
  22. zeb
    zeb WRInaute accro
    Inscrit:
    5 Décembre 2004
    Messages:
    12 021
    J'aime reçus:
    1
    J'ai écrit mon propre code pour cela.
     
  23. noren
    noren WRInaute accro
    Inscrit:
    8 Avril 2011
    Messages:
    2 816
    J'aime reçus:
    18
    ok, bon bin je vais voir si je ne vais pas mettre en SILENT en général et en exception uniquement lorsque je traite des transactions.

    l'avantage de laisser en mode exception : si un petit malin arrive fait planter une requete en faisant des tentative d'injections je pouvais créer un log et voir la requête tentée. En SILENT, pour avoir un retour des requêtes qui ont planté et sur mutualisé c’est plus embêtant.
     
  24. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 169
    J'aime reçus:
    346
    Oui.
     
  25. noren
    noren WRInaute accro
    Inscrit:
    8 Avril 2011
    Messages:
    2 816
    J'aime reçus:
    18
    Ok merci :wink:
     
Chargement...
Similar Threads - sécuriser injections SQL Forum Date
sécuriser upload fichier csv.gz Développement d'un site Web ou d'une appli mobile 9 Mars 2022
Sécuriser son formulaire de recherche (protection anti-robot) Développement d'un site Web ou d'une appli mobile 24 Février 2015
Quel outil pour sécuriser un site ? vérification périodique des fichiers Administration d'un site Web 21 Octobre 2011
Comment sécuriser le lien de mon produit numérique ? e-commerce 18 Août 2011
Sécuriser le fichier error_log par htaccess URL Rewriting et .htaccess 2 Avril 2010
Sécuriser/protéger un site contre d'éventuelles attaques Développement d'un site Web ou d'une appli mobile 12 Mars 2010
Sécuriser l'index du site du duplicate à cause des index multiples Débuter en référencement 18 Février 2010
Sécuriser un Cookie d'authentification Développement d'un site Web ou d'une appli mobile 7 Février 2010
sécuriser un service web ? Développement d'un site Web ou d'une appli mobile 29 Juin 2009
Sécuriser un blog Wordpress en 7 étapes Développement d'un site Web ou d'une appli mobile 28 Mai 2009
Sécuriser un script php de téléchargement de fichiers Développement d'un site Web ou d'une appli mobile 13 Mars 2009
Sécuriser son site Internet Développement d'un site Web ou d'une appli mobile 26 Septembre 2008
Sécuriser un champ textaera (TinyMCE) Développement d'un site Web ou d'une appli mobile 10 Août 2008
securiser un formulaire avec mot a retaper Développement d'un site Web ou d'une appli mobile 29 Juillet 2008
Sécuriser WordPress et IPB Administration d'un site Web 17 Avril 2008
Connexion PDO : comment sécuriser les champs de formulaire? Développement d'un site Web ou d'une appli mobile 16 Avril 2008
Sécuriser et protéger son site web Administration d'un site Web 2 Octobre 2007
Securiser mon formulaire mail ? avec les p'tites lettres :) Développement d'un site Web ou d'une appli mobile 24 Juin 2007
Hack, massmailing, ralentissement : comment sécuriser? Administration d'un site Web 12 Mars 2007
[article] Sécuriser son serveur LAMP Administration d'un site Web 18 Août 2006