Mysql
 sql >> Base de données >  >> RDS >> Mysql

éviter les injections MySQL avec la classe Zend_Db

J'ai écrit une grande partie du code pour les paramètres de base de données et les citations dans Zend Framework alors que j'étais le chef d'équipe du projet (jusqu'à la version 1.0).

J'ai essayé d'encourager les meilleures pratiques dans la mesure du possible, mais j'ai dû trouver un équilibre avec la facilité d'utilisation.

Notez que vous pouvez toujours examiner la valeur de chaîne d'un Zend_Db_Select objet, pour voir comment il a décidé de faire la citation.

print $select; // invokes __toString() method

Vous pouvez également utiliser le Zend_Db_Profiler pour inspecter le SQL exécuté en votre nom par Zend_Db .

$db->getProfiler()->setEnabled(true);
$db->update( ... );
print $db->getProfiler()->getLastQueryProfile()->getQuery(); 
print_r $db->getProfiler()->getLastQueryProfile()->getQueryParams(); 
$db->getProfiler()->setEnabled(false);

Voici quelques réponses à vos questions spécifiques :

  • Zend_Db_Select::where('last_name=?', $lname)

    Les valeurs sont citées de manière appropriée. Bien que le "? " ressemble à un espace réservé de paramètre, dans cette méthode, l'argument est en fait cité de manière appropriée et interpolé. Il ne s'agit donc pas d'un véritable paramètre de requête. En fait, les deux instructions suivantes produisent exactement la même requête que l'utilisation ci-dessus :

    $select->where( $db->quoteInto('last_name=?', $lname) );
    $select->where( 'last_name=' . $db->quote($lname) );
    

    Cependant, si vous passez un paramètre qui est un objet de type Zend_Db_Expr , alors ce n'est pas cité. Vous êtes responsable des risques d'injection SQL, car il s'agit d'une interpolation textuelle, pour prendre en charge les valeurs d'expression :

    $select->where('last_modified < ?', new Zend_Db_Expr('NOW()'))
    

    Toute autre partie de cette expression devant être citée ou délimitée relève de votre responsabilité. Par exemple, si vous interpolez des variables PHP dans l'expression, la sécurité est de votre responsabilité. Si vous avez des noms de colonnes qui sont des mots clés SQL, vous devez les délimiter vous-même avec quoteIdentifier() . Exemple :

    $select->where($db->quoteIdentifier('order').'=?', $myVariable)
    
  • Zend_Db_Adapter_Abstract::insert( array('colname' => 'value') )

    Le nom de la table et les noms des colonnes sont délimités, sauf si vous désactivez AUTO_QUOTE_IDENTIFIERS .

    Les valeurs sont paramétrées comme de vrais paramètres de requête (non interpolés). Sauf si la valeur est un Zend_Db_Expr objet, auquel cas il est interpolé textuellement, vous pouvez donc insérer des expressions ou NULL ou autre.

  • Zend_Db_Adapter_Abstract::update( array('colname' => 'value'), $where )

    Le nom de la table et les noms des colonnes sont délimités, sauf si vous désactivez AUTO_QUOTE_IDENTIFIERS .

    Les valeurs sont paramétrées, sauf si elles sont Zend_Db_Expr objets, comme dans insert() méthode.

    Le $where L'argument n'est pas du tout filtré, vous êtes donc responsable de tout risque d'injection SQL dans celui-ci. Vous pouvez utiliser le quoteInto() méthode pour rendre la citation plus pratique.