6
votes

Comment Sprintf () protège-t-il contre l'injection SQL?

J'ai entendu dire que sprintf () protège contre l'injection SQL. Est-ce vrai? Si oui, comment?

Pourquoi les gens recommandent d'écrire une requête comme celle-ci: xxx


2 commentaires

qui les gens recommandent une telle chose?


Ce que vous signifiez probablement, ce sont des déclarations préparées, qui est un sujet différent.


4 Réponses :


9
votes

Cela ne fait pas de protection. Utilisation de Sprintf facilite le plus de code lisible, puis déposer dans et hors d'une chaîne pour exécuter mysql_real_escape_string sur chacune des variables ... mais cet exemple n'échappe pas aux variables à la fin. Donc, cet avantage est perdu.

Si vous voulez une protection décente, utilisez quelque chose qui fournit Paramètres liés .


1 commentaires

Ooops. stupide_overlong_not_fake_function_names est trop facile pour introduire des fautes de frappe à cette heure du matin. :)



10
votes

Sprintf ne vous protégera pas! Il ne remplace que le % s

Vous devez alors: xxx

est plus sûr d'injection

note: je suggère vous jetez un coup d'œil à PDO , c'est ce que j'aime utiliser pour dbconections et requêtes


2 commentaires

@beardthatcode mysqli_real_escape_string devrait être utilisé à la place. Les fonctions MYSQL_ * ont été obsolètes depuis 5,5 PHP et ont été supprimées depuis PHP 7. et par la voie. MySQLI soutient également des déclarations préparées. Personnellement, je recommanderais que toutes les variables entrantes comme $ _GET, $ _Post, $ _Request soient exécutées via un pare-feu d'application Web (WAF). J'ai également lu ici que $ _files devraient être vérifiés, mais buti ne comprend pas pourquoi ce superglobal pourrait contenir du contenu malcient.


Aussi, je jette toujours des noms de table et de rangée dans les backtsks. Par conséquent, la déclaration devient plus lisible. Aussi avec l'utilisation de backtsticks, vous n'avez pas à vous soucier des noms réservés. Donc, vous pouvez par exemple le nom d'une commande de ligne de tri sans obtenir une erreur. Sans que vous en aurez un.



3
votes

Utiliser Sprintf peut protéger contre l'injection SQL pour les champs numériques: xxx

à l'aide de Sprintf de cette manière, vous pouvez être sûr que $ col1 sera converti en un entier - bien que cela puisse Générez une erreur ou un avertissement, si ce n'est pas vraiment un entier.

La manière appropriée de protéger contre l'injection SQL est de vérifier toutes vos valeurs d'entrée et de s'échapper. Mais c'est beaucoup plus profondément couvert dans d'autres questions, je ne vais donc pas entrer dans les détails ici.


6 commentaires

Mais avec des entiers, vous n'auriez plus d'utiliser des précautions spéciales de toute façon.


Assurez-vous que si l'entrée-entrée "INTEGER" ressemble à ceci: "; Les utilisateurs de la table de déposer;"?


Ensuite, ce n'est pas un entier, très simple. Je n'ai pas dit que vous pouviez chuter de type chèque de type.


Vous avez dit "pas de précautions spéciales" - je envisagerais de vérifier la vérification d'une précaution. Dans tous les cas, l'utilisation de Sprintf est un moyen idiot d'essayer de protéger contre l'injection SQL pour toute donnée.


Ou simplement $ col1 = $ col1 + 0; avant de l'utiliser.


ou plus court $ col1 + = 0;



1
votes

Ce n'est évidemment pas et si vous avez réellement lu cela dans un livre ou un didacticiel, je devais le jeter automatiquement pour référence future.

Cependant, il peut être un moyen pratique de générer une production qui nécessite un traitement ultérieur. Veuillez comparer: p>

// Fictional DB abstraction layer
$sql = 'SELECT foo_id
    FROM foo
    WHERE name=:name AND status=:status';
$params = array(
    'name' => $name,
    'status' => $status,
);
$result = $db->run($sql, $params);


0 commentaires