viernes, 16 de abril de 2010

Cláusulas dinámicas en Groovy: versión a prueba de Inyección SQL

Hola,

En una entrada anterior comentamos cómo crear dinámicamente una sentencia SQL partiendo de una lista de valores para una columna.
Ya advertimos que debido al uso de la concatenación de cadenas, el método sólo era válido si teníamos totalmente controlados los parámetros de entrada, ya que si no podíamos sufrir un ataque de Inyección SQL, pero con un poco más de trabajo, podemos crear una solución que nos proteja contra estos ataques, y es la que presentamos ahora:
Suponiendo la misma tabla que en la entrada anterior, lo que haremos en este caso es que la cadenas que vamos a concatenar colocará interrogantes (?) donde deberían ir los valores y luego pasaremos la lista de valores a la sentencia SQL para que la ejecute. Haciéndolo así Groovy usará un PreparedStatement para asignar los valores de los parámetros y estaremos protegidos contra un posible ataque de Inyección SQL. Veámoslo:

def parametrosMultiples = 'ABE,MUL,TAC,FRO' // o podría ser sólo 'ABE' o null
def listaParametrosMultiples = parametrosMultiples.split(',')
def condicionOR = listaParametrosMultiples.collect({'?'}).join(' OR TAB_CAMPO=')
def clausulaWhere = parametrosMultiples ? "WHERE TAB_CAMPO=${condicionOR}" : ''
def sentencia = "SELECT * FROM TAPP_TABLA ${clausulaWhere}" 
println sentencia
Resultado:
SELECT * FROM TAPP_TABLA WHERE TAB_CAMPO=? OR TAB_CAMPO=? OR TAB_CAMPO=? OR TAB_CAMPO=?

Y al ejecutarlo, le pasamos la lista de valores como parámetros:
//...
def sql = new Sql(ds); // ds es un DataSource que habremos obtenido de algún lado
sql.eachRow( sentencia
     ,Arrays.asList(listaParametrosMultiples)
     ,{
        ... // Aquí haremos algo para
        // cada fila resultado (it)
      }
     );
//...

Básicamente lo único que hemos hecho es usar la función collect para sustituir los valores del array de parámetros por interrogantes, y luego convertir el array en una lista, con Arrays.asList() para poder pasárselo al método eachRow.

Con estos sencillos cambios, cerramos un posible agujero en la seguridad.

Eso es todo de momento. ¡Feliz fin de semana!

EJ
Happy Coding!