IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Requêtes préparées et injections SQL


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut Requêtes préparées et injections SQL
    Bonjour,

    je sais que via les requêtes préparées, il est impossible de subir des attaques de type injection, mais je n'ai jamais compris le pourquoi du comment

    Est-ce PDO qui caste automatiquement les variables connaissant le type à l'avance des champs en base ou...?

    Merci de vos éclairssissements

  2. #2
    Membre Expert Avatar de nosferapti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 157
    Par défaut
    PDO échappe automatiquement les données si tu les passe par les méthodes "bind*" ou par "execute"

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    625
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 625
    Par défaut
    En prenant l'exemple que tu attaques une base mySql,

    PDO::PARAM_STRING appliquera un équivalent de mysql_real_escape_string() sur la variable liée.

    PDO::PARAM_INT castera la variable en entier, si tu lui passes une chaîne non numérique, ça te rentrera 0 en base.

    Edit : fichus smileys automatiques !

  4. #4
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Salut

    Citation Envoyé par Petibidon
    PDO::PARAM_INT castera la variable en entier, si tu lui passes une chaîne non numérique, ça te rentrera 0 en base.
    J'avais fais pas mal d'essai sur ce point là, et j'en avais conclu que PDO ne typait (ou castait) rien du tout.
    Les constantres PARAM_INT, PARAM_NULL, etc ... ne provoquait strictement rien sur les valeurs, c'est comme si on ne mettais rien.

    J'avais créé un topic la dessus pour avoir des avis d'ailleurs.
    -> BindValue() : Paramètre data_type sans effet ?
    Apparemment, et selon Julp ça dépendrait du SGBD, du driver/pilote utilisé.

    Pour PDO (Php5.3.0) et MySQL5.1.36, ça donne pas grand chose, du moins, selon mes essais.


    A coté de ça, il me semble que les requêtes préparées offrent énormément de sécurité contre les SQL injections.

  5. #5
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Par défaut
    C'est la séparation des données de la requête même (les valeurs des colonnes dans une requête update/insert ou au niveau de la clause where notamment) qui assure l'absence d'injections. C'est ensuite totalement géré par le SGBD. La requête préparée aura été analysée/compilée par le SGBD avant la prise en compte des valeurs des paramètres, ces dernières sont donc totalement indépendantes et sans influence.

    Les (potentielles) conversions effectuées par PHP ne sont pas liées, elles n'assurent la correspondance de type (PHP vers SGBD) que lorsque nécessaire (d'autant que certaines peuvent être implicitement réalisées par le SGBD).

  6. #6
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Citation Envoyé par Julp
    Les (potentielles) conversions effectuées par PHP ne sont pas liées, elles n'assurent la correspondance de type (PHP vers SGBD) que lorsque nécessaire
    C'est vraiment potentielles, car pour MySQL ce n'est jamais le cas malheureusement.

    Si, (par exemple) on met comme paramètre PARAM_NULL et que coté Bdd le champ accepte une valeur nulle, et bien dans tous les cas ce n'est pas une valeur nulle qui sera insérée, au mieux, ça sera vide.
    Enfin, si la valeur n'est pas nulle j'entends. Ca veut bien dire que PARAM_NULL n'a aucune relation entre PDO et MySQL.
    Si on veux mettre une valeur nulle, on a pas d'autre choix que la valeur soit vraiment nulle, donc on doit traiter le cas avant PDO.
    C'est nulle ...


    Si ce paramètre n'est pas là pour résoudre ce genre cas (comme caster une variable), alors je dirais qu'il est trompeur, il laisserait sous entendre que ...
    Je serais tombé dans l'panneau, si on peu dire.


    Pour donner mon sentiment sur les requêtes préparées, et sauf erreur de ma part, vous me direz si je me trompe , mais il me semble que certains y feraient un peu trop confiance.

    Si on fait une requête comme celle ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $sql = 'SELECT champ FROM table WHERE user_id = '.$_POST['user_id'];
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    Ici, et théoriquement, on ne serait pas protégé contre une éventuelle injection venant de $_POST.

    Il faudrait au moins binder (si on peu dire) la valeur extérieure.
    Comme par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $sql = 'SELECT champ FROM table WHERE user_id = ?';
    $stmt = $pdo->prepare($sql);
    $stmt->execute(array($_POST['user_id']));
    Ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $sql = 'SELECT champ FROM table WHERE user_id = :user_id';
    $stmt = $pdo->prepare($sql);
    $stmt->bindValue(':user_id', $_POST['user_id'], PDO::PARAM_INT);
    $stmt->execute();
    Ici on profite pleinement des requêtes préparées pour le coté sécurité.

Discussions similaires

  1. Requête analyse croisée sous SQL SERVER
    Par motus_z dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 23/02/2006, 16h54
  2. Réponses: 10
    Dernier message: 25/10/2005, 16h09
  3. Requêtes analyses croisées sous SQL Server 2000
    Par callo dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 24/09/2005, 19h27
  4. Pb Requête Corrélées sur MS SQL-SERVER2000
    Par Pongo dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/09/2005, 16h08
  5. État, Requète et clause Where(SQL)
    Par Philippe299 dans le forum Access
    Réponses: 2
    Dernier message: 12/09/2005, 00h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo