En Postgres, ¿las consultas preparadas y las funciones definidas por el usuario son equivalentes como un mecanismo para protegerse contra la inyección de SQL ?
¿Hay ventajas particulares en un enfoque sobre el otro?
En Postgres, ¿las consultas preparadas y las funciones definidas por el usuario son equivalentes como un mecanismo para protegerse contra la inyección de SQL ?
¿Hay ventajas particulares en un enfoque sobre el otro?
Respuestas:
Depende.
Con LANGUAGE sql
, la respuesta es generalmente sí .
Los parámetros pasados se tratan como valores y la inyección SQL no es posible, siempre y cuando no llame a funciones inseguras desde el cuerpo y pase parámetros.
Con LANGUAGE plpgsql
, la respuesta es normalmente sí .
Sin embargo , PL / pgSQL permite un SQL dinámico donde los parámetros (o partes) pasados se concatenan a una cadena de consulta y se ejecutan con EXECUTE
. Esto puede convertir la entrada del usuario a código SQL y hace posible la inyección SQL . No se puede saber desde afuera si el cuerpo de la función lo maneja correctamente. Se proporcionan herramientas.
Solo use SQL dinámico donde lo necesite. Las declaraciones SQL simples que usan parámetros como valores son seguras contra la inyección SQL como las funciones SQL.
Para SQL dinámico , preferiblemente pase valores como valores con:
USING
cláusula Ejemplo .Hace que la inyección de SQL sea imposible en el principal.
Si concatena valores en la cadena SQL, use:
Envuelve las cadenas entre comillas simples de forma segura, evitando así los errores de sintaxis y la inyección de SQL.
Parámetros de proceso que se tratarán como identificadores en la cadena SQL con:
format()
con especificador de formato%I
. Ejemplo .quote_ident()
. Ejemplo .regclass
para nombres de tabla: _tbl::regclass
. Ejemplo .Encierra cadenas entre comillas dobles de forma segura donde sea necesario , evitando así los errores de sintaxis y la inyección de SQL.
Relacionado:
Nunca construyas una cadena a partir de la entrada del usuario y la ejecutes. Esto incluye identificadores, pasados directamente por un usuario o extraídos de un catálogo del sistema. ¡Todos deben tratarse como una entrada del usuario y citarse de manera segura al crear SQL dinámico!
Más información sobre las implicaciones de rendimiento en esta respuesta relacionada:
Conceptos básicos sobre la inyección SQL:
Consideraciones similares se aplican a otros lenguajes del lado del servidor que permiten SQL dinámico.
USING
cláusula para pasar valores EXECUTE
siempre que sea posible. Usted podría llamar a una función PL / pgSQL desde dentro de una función SQL y pasar parámetros. Por lo tanto, para ser absolutamente correcto, está seguro siempre que no llame a ninguna función insegura directa o indirectamente. Si todas sus funciones se realizan correctamente, eso no puede suceder.