Comment désinfecter SQL sans utiliser d'instructions préparées
Pour certaines instructions sql je ne peux pas utiliser un prêt de tresorerie, par exemple:
SELECT MAX(AGE) FROM ?
Par exemple quand je veux faire varier la table. Est-il un utilitaire qui nettoie sql en Java? Il y en a un en ruby.
source d'informationauteur mr.gaffo
Vous devez vous connecter pour publier un commentaire.
Droit, déclaration préparée à l'avance les paramètres de la requête peut être utilisée uniquement si vous utilisez une seule valeur littérale. Vous ne pouvez pas utiliser un paramètre pour un nom de table, un nom de colonne, une liste de valeurs, ou de toute autre syntaxe SQL.
De sorte que vous avez à interpoler votre application variable dans la chaîne SQL et de citer la chaîne de façon appropriée. N'utilisez citant pour délimiter votre table identificateur de nom, et d'échapper à la citation de la chaîne par le doublant:
Par exemple, si votre nom de la table est littéralement
table"name
et votre SGBDR identificateur de caractère de guillemet est"
puissql
doit contenir une chaîne de caractères comme:Je suis également d'accord avec @ChssPly76 commentaire -- il est préférable si votre entrée utilisateur n'est pas réellement du sens littéral du nom de la table, mais un signifiant que votre code correspond à un nom de table, ce qui permet ensuite interpoler dans la requête SQL. Cela vous donne plus d'assurance qu'aucune injection SQL peut se produire.
Pas possible. Le mieux ce que vous pouvez faire est d'utiliser
String#format()
.Noter que ce n'est pas d'éviter les risques d'injection SQL. Si le
tablename
est un utilisateur/client-contrôlée de la valeur, vous avez besoin de désinfecter à l'aide deString#replaceAll()
.Espère que cette aide.
[Edit] j'ajoute: ne PAS utiliser pour les valeurs de la colonne où vous pouvez utiliser
PreparedStatement
pour. Continuer à utiliser de la manière habituelle pour toutes les valeurs de la colonne.[Edit2] le Mieux serait de ne pas laisser l'utilisateur/client doit être en mesure d'entrer le nom de la table de la manière de le vouloir, mais mieux présenter une liste déroulante contenant tous les valide tablenames (que vous pouvez obtenir par
DatabaseMetaData#getCatalogs()
) dans l'INTERFACE utilisateur afin que l'utilisateur/client peut sélectionner. N'oubliez pas de vérifier dans le côté serveur si la sélection est valide parce que l'on pourrait usurper les paramètres de la requête.Dans ce cas, vous pouvez valider le nom de la table dans la liste des tables disponibles, par l'obtention de la table de cotation de la DatabaseMetaData. En réalité, il serait probablement être plus facile d'utiliser une expression régulière pour la bande des espaces, peut-être aussi certains mots réservés sql, ";", etc à partir de la chaîne avant d'utiliser quelque chose comme Chaîne de caractères.format pour construire votre instruction sql complète.
La raison pour laquelle vous ne pouvez pas utiliser preparedStatement est parce qu'il est probablement entourant le nom de la table en "s et de prendre la fuite comme une chaîne de caractères.