Comment protéger une requête ODBC de l'injection SQL

Quelle serait la meilleure façon de protéger cette requête de l'injection sql? Cet exemple n'est qu'un exemple, j'ai lu quelques articles sur Internet mais je ne peux pas me préoccuper des requêtes paramétrées. Tout lien vers des articles utiles permettra de voter, mais je pense que l'exemple de cet exemple m'aiderait le mieux.

$id = $_GET["id"]; $connection = odbc_connect("Driver={SQL Server};Server=SERVERNAME;Database=DATABASE-NAME;", "USERNAME", "PASSWORD"); $query = "SELECT id firstname secondname from user where id = $id"; $result = odbc_exec($connection, $query); while ($data[] = odbc_fetch_array($result)); odbc_close($connection); 

Merci,

EDIT: Je ne l'ai pas rendu évident, mais j'utilise SQL Server et non mysql. Ce n'est qu'un exemple, ce ne sera pas toujours un numéro sur lequel je search. Ce serait bien si la réponse utilisée a paramétré requirejs autant de personnes qui suggèrent cela et ce serait la même chose pour toutes les requêtes au lieu de différents types de validation pour différents types d'inputs d'users.

Utilisez les déclarations préparées. Créez d'abord une déclaration avec la fonction odbc_prepare (), puis passez les parameters et exécutez-le en utilisant odbc_execute ().

C'est beaucoup plus sûr et plus facile que d'échapper à la string vous-même.

Les conseils de Lewis Bassett concernant PDO sont bons, mais il est possible d'utiliser des instructions préparées avec ODBC sans devoir passer à PDO.

Exemple de code, non testé!

 try { $dbh = new PDO(CONNECTION_DETAILS_GO_HERE); $query = 'SELECT id firstname secondname from user where id = :id'; $stmt = $dbh->prepare($query); $stmt->bindParam(':id', $id, PDO::PARAM_STR); $result = $stmt->execute(); $data = $stmt->fetchAll(); } catch (PDOException $e) echo 'Problem: ', $e->getMessage; } 

Remarque: $ e-> getMessage (); peut exposer des choses que vous ne voulez pas exposer, donc vous voudrez probablement faire quelque chose de différent sur cette ligne lorsque votre code sera mis en ligne. Il est cependant utile pour le debugging.

Edit: Vous ne savez pas si vous vouliez un exemple PDO ou ODBC, mais c'est essentiellement le même pour les deux.

Edit: Si vous me décrochez, laissez un commentaire et dites-moi pourquoi.

Je pense que les objects PDO sont les meilleurs.

En un mot, voici comment vous les utilisez.

 $databaseConnection = new PDO('mysql:host='. $host .';dbname=' . $databaseName, $username, $password); $sqlCommand = 'SELECT foo FROM bar WHERE baz=:baz_value;'; $parameters = array( ':baz_value' => 'some value' ); $preparedStatement = $databaseConnection->prepare($sqlCommand); $preparedStatement->execute($parameters); while($row = $preparedStatement->fetch(PDO::FETCH_ASSOC)) { echo $row['foo'] . '<br />'; } 

Les valeurs que vous entrez pour les critères SELECT sont remplacées par des parameters (comme :field_value ) qui commencent par deux points. Les parameters sont ensuite atsortingbués dans un tableau qui est passé séparément.

Il s'agit d'une meilleure façon de traiter les requêtes SQL à mon avis.

Les parameters sont envoyés à la database séparément de la requête et protègent de l'injection SQL.

Pour commencer, faites attention aux variables que vous utilisez dans vos requêtes, en particulier celles provenant de sources externes telles que $ _GET, $ _POST, $ _COOKIE et $ _FILES . Pour utiliser des variables dans vos requêtes, vous devez:

  • Transformez datatables numériques en entier ou flottent (selon le cas)
  • Utilisez un échappement approprié pour échapper à d'autres données

Un exemple simple pour les bases de données mysql:

 $id = $_GET["id"]; // contains: OR 1 = 1 $name = $_GET["name"]; // contains: ' OR '' =' $query = "SELECT * FROM table WHERE id = " . intval($id) . " AND name = '" . mysql_real_escape_ssortingng($name) . "'"; // SELECT * FROM table WHERE id = 0 AND name = '\' OR \'\' =\'' 

Pour d'autres bases de données, la pratique d'échappement varie. Mais généralement, vous êtes censé échapper au ' personnage avec '' , alors:

 $id = $_GET["id"]; // contains: OR 1 = 1 $name = $_GET["name"]; // contains: ' OR '' =' $query = "SELECT * FROM table WHERE id = " . intval($id) . " AND name = '" . str_replace("'", "''", $name) . "'"; // SELECT * FROM table WHERE id = 0 AND name = ''' OR '''' =''' 

Cela dit, vous pourriez peut-être passer à PDO . Il vous permet d'utiliser des instructions préparées , le pilote PDO fait tout son échappement.

La variante mysql est venue avec une méthode appelée mysql_real_escape_ssortingng, ce qui était approprié pour la version de SQL ciblée. La meilleure chose que vous pouvez faire est d'écrire une méthode pour échapper à l'Id. Il est important que votre méthode d'échappement soit appropriée pour la database cible . Vous pouvez également effectuer une vérification de type de base comme is_numeric pour les inputs numériques, rejeter immédiatement les injections de string SQL.

Voir Comment échapper à des strings dans SQL Server à l'aide de PHP? et suivre certains des liens associés pour des exemples explicites