Estoy generando algunos SQL dinámicos y me gustaría asegurarme de que mi código esté a salvo de SQL injection.Sanitize nombre de tabla/columna en SQL dinámico en .NET? (Impedir ataques de inyección SQL)
En aras de la discusión aquí es un ejemplo de cómo mínimo que se genera:
var sql = string.Format("INSERT INTO {0} ({1}) VALUES (@value)",
tableName, columnName);
En lo anterior, tableName
, columnName
, y todo lo que está obligado a @value
provenir de una fuente no confiable. Dado que los marcadores de posición se están utilizando, @value
está a salvo de los ataques de inyección de SQL y puede ignorarse. (El comando se ejecuta a través de SqlCommand.)
Sin embargo, tableName
y columnName
no puede ser obligado como marcadores de posición y para ello son vulnerables a ataques de inyección. Como este es un escenario "verdaderamente dinámico", no hay una lista blanca de tableName
o columnName
disponible.
La pregunta es, pues:
¿Existe una norma , una función de manera de comprobar y/o desinfectar tableName
y columnName
? (SqlConnection, o una clase auxiliar, etc.) En caso negativo, ¿cuál es una buena forma de realizar esta tarea sin usando una biblioteca de terceros?
Notas:
- todos los identificadores de SQL, incluyendo el esquema, debe por aceptada: por ejemplo,
[schema].[My Table].column
es tan "seguro" comotable1
. - Puede esterilizar los identificadores o detectar un identificador no válido. (No es necesario para asegurar que la tabla/columna es realmente válida en su contexto; el SQL resultante puede ser válida, pero debe ser "seguro".)
Actualización:
acaba de encontrar esto, y pensó que era algo interesante: ¿Hay una función SqlFunctions.QuoteName en .NET4 (EF4?). De acuerdo, no es realmente ayúdame aquí ...
Tiene razón, de hecho es SQL Server. Me estoy inclinando por una ruta de expresión regular * aceptada mínimamente *, pero esperaba que existiera algo prefabricado (y probado ;-). Me gusta mucho la idea adicional de compararla con los metadatos del esquema. –
Si usa una consulta parametrizada para probar la tabla/esquema, entonces verifique la existencia de cada nombre de columna en el código contra la lista completa de nombres de columna para la tabla, entonces realmente no necesita realizar ninguna verificación de validez en los valores entrantes , que sería lo último en minimización :). –
Bueno, es una * pequeña * implementación más grande :) –