Question

Nous avons une application Java qui communique avec plusieurs bases de données SQL Server sur le même la boîte.Le nombre de noms et de ces bases de données varient.En gros, nous utilisons presque exclusivement des procédures stockées avec CallableStatement pour accéder aux bases de données.Nous sommes extrêmement bien sur la manière d'éviter l'injection SQL et l'utilisation de variables de liaison.

La seule préoccupation est que le nom de base de données elle-même est concaténé dans le SQL que l'on passe à la CallableStatement en tant que tel:

"{call [" + dbName + ".dbo." + procName + "(?, ?, ?)}"

nomproc est codée en dur dans les classes enfant à l'aide d'une méthode de modèle de modèle, de sorte que la chaîne est garanti en toute sécurité.

dbName est définie à l'extérieur.J'ai essayé de réglage dbName à toutes sortes de modèles pour échapper à la syntaxe et à exploiter sur mon environnement de développement et ont été infructueuses.

J'ai mis à la suite de produire la suite d'appels SQL (table et proc noms ont été changés pour protéger les innocents):

securitytest].nx_proc()};delete from poor_victim_table;

devient

{call [securitytest].nx_proc()};delete from poor_victim_table;].dbo.proper_proc_name()}

et

securitytest].nx_proc()};exec('delete from poor_victim_table');

devient

{call [securitytest].nx_proc()};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}

Résultats dans Incorrect syntax near ')'. et poor_victim_table a encore des lignes.J'ai utilisé truncate table, drop table et drop database et quand ils n'ont pas de travail, je suis passé de simple delete pour écarter les paramètres de sécurité.

Si j'utilise un proc qui prend lier des paramètres, j'ai toujours un décalage entre le nombre de paramètres et paramètres fournis tels que The index 1 is out of range..

securitytest]};exec('delete from poor_victim_table');

devient

{call [securitytest]};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}

Tous les chemins semblent mener à une erreur d'exécution et le SQL n'est pas exécutée.Bien sûr, ce qui est excellent.Mais je veux être sûr que c'est défaillante car il ne peut pas réussir et ne manque pas parce que je suis à défaut d'essayer la bonne combinaison.

L'opinion populaire / légende urbaine n'est qu'à l'aide d'une procédure stockée, vous met à l'abri de l'injection SQL, mais je préfère ne pas la confiance absolue des déclarations comme ça, quand il s'agit de la sécurité.

Après des recherches sur ce depuis un moment, le meilleur, je suis venu avec est-ce stackoverflow question: Injection de code SQL - aucun danger sur appel de procédure stockée (sur les iSeries)?.Il semble à l'appui de l'aide CallableStatement, car il vous protège contre l'injection SQL à moins que votre proc code lui-même fait le SQL dynamique d'un paramètre d'entrée.

Donc, ma question à la communauté est, en supposant que le code SQL dans une proc est sûr, ne l'aide CallableStatement dans JDBC vraiment prévenir l'injection SQL?Ou le pilote SQL Server analyser la chaîne de manière à éviter, mais les autres pilotes ne peuvent pas?Ou ne suis-je pas assez d'efforts?

Si elle est sans danger, comment est-ce la garantie faite?Est-ce dû à la syntaxe abstraite de l'aide { call blah(?) } ce qui n'est pas réel SQL, mais se traduit en SQL?

Était-ce utile?

La solution

Vous devrait être sûr, mais tout comme vous, je n'aurais pas confiance, surtout si vous êtes en interface avec les différentes bases de données à l'aide de différents pilotes JDBC etc.

Si j'étais vous, avant de faire la déclaration que vous avez posté, j'avais assurez-vous de vérifier si la dbName contient rien mais des lettres, des chiffres, et éventuellement un trait de soulignement.Cela devrait permettre à tous les valide dbNames, et de prévenir tous les types de jouer avec elle.

Autres conseils

Vérifiez votre connexion db url, je pense que c'est se référer statique db, donc si vous écrivez le nom db dans appelable énoncé, cela va générer problème db à chaque fois que le nom a été changé, votre code comme matrice (la plupart des endroits pour changer), donc ne pas utiliser db nom dans la requête, mais vous pouvez créer des objets différents pour les différentes db connexion ou de différentes classes d'aide pour cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top