No analices SQL para hacer que un ejecutor de consultas sea de solo lectura

Deja de intentar asegurar tu base de datos buscando palabras clave en las cadenas de SQL.

Si construyes una herramienta para ejecutar SQL, querrás un modo de solo lectura. Querrás evitar que un UPDATE accidental elimine tus datos. Tu primer pensamiento podría ser bloquear palabras como DELETE o DROP.

No hagas esto.

Las comprobaciones de cadenas son fáciles de eludir. Un usuario puede usar una cláusula WITH para ocultar un DELETE. Pueden usar comentarios para ocultar comandos. Pueden llamar a una función que escriba en una tabla. Terminarás jugando un juego perdido de whack-a-mole.

Deja que la base de datos se encargue de la seguridad.

Postgres tiene una función integrada para esto. Puedes declarar una transacción como de solo lectura. El servidor rechazará entonces cualquier comando de escritura. Esto cubre CTEs, funciones y DDL.

Aquí te mostramos cómo implementarlo correctamente en Python:

Este enfoque no inspecciona el texto SQL. La consulta llega al servidor exactamente como fue escrita. Le estás diciendo al motor que haga cumplir la regla.

La seguridad requiere dos partes:

  1. Protección contra escrituras: Usa transacciones de solo lectura.
  2. Protección contra el abuso de recursos: Usa tiempos de espera (timeouts) y límites de filas.

Una consulta de solo lectura aún puede colapsar tu sistema con un join masivo. Una transacción de solo lectura detiene las escrituras, pero no detiene el uso intensivo de recursos. Necesitas ambas para que el SQL ad-hoc sea seguro.

Deja de analizar SQL. Pídele a la base de datos que haga su trabajo.

Fuente: https://dev.to/hitoshi1964/dont-parse-sql-to-make-a-query-runner-read-only-b62