Pregunta

Tenemos una aplicación Java que se comunica con múltiples bases de datos de SQL Server en el mismo cuadro.El número y los nombres de estas bases de datos varían.En general, utilizamos casi exclusivamente procedimientos almacenados con CallableStatement para acceder a las bases de datos.Somos extremadamente buenos para evitar la inyección SQL y usar variables de vinculación.

La única área de preocupación es que el nombre de la base de datos en sí está concatenado en el SQL que pasamos a CallableStatement como tal:

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

procName está codificado en clases secundarias utilizando un patrón de método de plantilla, por lo que se garantiza que la cadena es segura.

dbName se define externamente.Intenté configurar dbName en todo tipo de patrones para escapar de la sintaxis y explotar esto en mi entorno de desarrollo y no tuve éxito.

Lo configuré de la siguiente manera para producir las siguientes llamadas SQL (los nombres de tabla y proceso cambiaron para proteger a los inocentes):

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

se convierte

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

y

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

se convierte

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

Resultados en Incorrect syntax near ')'. y poor_victim_table todavía tiene filas.He usado truncate table, drop table y drop database y cuando no funcionaron, cambié a simple delete para descartar configuraciones de seguridad.

Si uso un proceso que toma parámetros de enlace, siempre obtengo una discrepancia entre la cantidad de parámetros esperados y los parámetros proporcionados, como The index 1 is out of range..

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

se convierte

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

Todos los caminos parecen conducir a un error de tiempo de ejecución y el SQL no se ejecuta.Por supuesto, esto es genial.Pero quiero asegurarme de que esté fallando porque no puedo tener éxito y no fracasar porque no logro probar la combinación correcta.

La opinión popular/mito urbano es que usar un procedimiento almacenado te hace inmune a la inyección SQL, pero prefiero no confiar en declaraciones absolutas como esa cuando se trata de seguridad.

Después de investigar esto por un tiempo, lo mejor que se me ocurrió es esta pregunta de stackoverflow: Inyección SQL: ¿no hay peligro en la llamada a procedimiento almacenado (en iSeries)?.Parece admitir el uso de CallableStatement porque lo protege de la inyección de SQL a menos que su código de proceso genere SQL dinámico a partir de un parámetro de entrada.

Entonces, mi pregunta para la comunidad es, suponiendo que el código SQL en un proceso sea seguro, ¿el uso de CallableStatement en JDBC realmente previene la inyección de SQL?¿O el controlador de SQL Server analiza la cadena de una manera que lo impide, pero es posible que otros controladores no lo hagan?¿O no me estoy esforzando lo suficiente?

Si es seguro, ¿cómo se hace esa garantía?¿Se debe a la sintaxis abstracta del uso? { call blah(?) } ¿Cuál no es SQL real, pero se traduce a SQL?

¿Fue útil?

Solución

Usted debería estar a salvo, pero al igual que usted, no lo confiaría, especialmente si está conectando a diferentes bases de datos utilizando diferentes controladores JDBC, etc.

Si yo fuera usted, antes de la declaración que publicó, me aseguraría de verificar si el DBName contiene algo más que letras, dígitos y, posiblemente, un subrayado.Esto debería permitir todos los nombres de DBN válidos, y evitar todo tipo de desorden.

Otros consejos

Revise su URL de conexión DB, creo que se refiere a la DB estática, por lo que si escribe el nombre de DB en la declaración Callable, esto generará problemas cuando cambió el nombre de DB, su código como MUERTE (la mayoría de los lugares para cambiar), así que noUse el nombre de DB en consulta, pero puede crear diferentes objetos para una conexión DB diferente o diferentes clases de ayuda para eso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top