Por qué un allowlist de operaciones no es suficiente: el caso del UPDATE sin WHERE

Los allowlists bloquean por el primer token. El AST parsing evalúa la semántica completa. La diferencia importa cuando el agente de IA genera exactamente los patrones que el allowlist no puede detectar.

8 min de lectura
AST PARSING SEGURIDAD SQL

El problema con los allowlists

Cuando los equipos de ingeniería piensan en proteger una base de datos de queries de LLMs, la primera idea suele ser un allowlist: permitir solo SELECT, bloquear DELETE y DROP.

El problema es que los allowlists operan sobre el primer token de la query. SELECT siempre pasa. DELETE siempre bloquea. Pero un agente de IA inteligente genera queries que el allowlist no puede clasificar correctamente.

Un allowlist no sabe la diferencia entre UPDATE users SET status = "inactive" WHERE id = $1 y UPDATE users SET status = "deleted".

Vericto evalúa el árbol completo en profundidad. No importa en qué nivel esté el nodo destructivo — si está en el árbol, se detecta.

Lo que un allowlist no puede detectar

Estos son los cuatro patrones que los agentes de IA generan con frecuencia y que un allowlist no puede detectar:

1. UPDATE sin WHERE

-- Un agente responde a "actualiza el precio del producto"
-- con contexto ambiguo y genera esto:
UPDATE products SET price = 0;

Modifica todas las filas de la tabla. Sintácticamente válido, semánticamente catastrófico.

2. DELETE con WHERE siempre verdadero

-- El LLM fue instruido para "limpiar registros viejos" pero
-- generó una condición trivialmente verdadera:
DELETE FROM sessions WHERE 1=1;

El allowlist lo bloquea por ser DELETE. Pero el agente puede reformularlo como un UPDATE masivo.

3. TRUNCATE dentro de una CTE

-- Patrón observado en agentes que construyen queries multi-step:
WITH cleanup AS (
  SELECT id FROM old_data
)
TRUNCATE TABLE orders;

La query empieza con WITH — un allowlist basado en primer token no lo detecta como TRUNCATE.

4. DROP TABLE en subquery anidada

-- Raro pero documentado en modelos con function calling agresivo:
DO $$
BEGIN
  DROP TABLE IF EXISTS users;
END $$;

Documentado en modelos de razonamiento avanzados. La query exterior puede ser un SELECT inocente.

Cómo funciona el AST parsing frente a estos casos

El AST (Abstract Syntax Tree) es la representación estructurada de una query. En lugar de evaluar el texto, Vericto evalúa el árbol semántico.

Para un UPDATE sin WHERE, el árbol tiene un nodo UpdateStmt con la propiedad whereClause = null. Para una CTE con TRUNCATE, el árbol tiene un nodo CommonTableExpr que contiene un TruncateStmt.

UpdateStmt
  ├── relation: "products"
  ├── targetList:
  │   └── ResTarget
  │       ├── name: "price"
  │       └── val: Integer(0)
  └── whereClause: NULL  ← el nodo que activa VERICTO-042

VERICTO-042 detecta UPDATE sin WHERE. VERICTO-031 detecta UPDATE sin WHERE en CTEs. Ambas reglas están activas por defecto.

El patrón WHERE 1=1 es el caso más común. El allowlist lo permite porque es un SELECT. El AST parsing detecta que el WHERE es trivialmente verdadero.

DeleteStmt
  ├── relation: "sessions"
  └── whereClause:
      └── A_Expr
          ├── kind: AEXPR_OP
          ├── name: "="
          ├── lexpr: Integer(1)
          └── rexpr: Integer(1)  ← ambos operandos son literales iguales
                                  → evaluable estáticamente → siempre true

El AST parsing produce el mismo resultado para la misma query, siempre. Puedes escribir un test que verifique el comportamiento exacto. Puedes auditar la decisión de bloqueo. Puedes certificar el control.

¿No es suficiente con los permisos de base de datos?

Es la objeción más común. "Si el usuario de la DB solo tiene SELECT, no puede hacer daño." El problema es que esto no es cierto en la práctica.

El principio de least privilege es correcto, pero aplicarlo correctamente a agentes de IA es notoriamente difícil. Vericto complementa los permisos con una capa semántica.

Los permisos y el AST parsing son capas complementarias. Los permisos limitan lo que el agente puede hacer. El AST parsing valida que lo que hace tenga sentido.

Los permisos de base de datos y el AST parsing son capas de defensa complementarias, no alternativas. Vericto no reemplaza los permisos — los complementa con validación semántica.

Por qué importa que sea determinístico

La alternativa al AST parsing para detectar queries peligrosas es un modelo de ML. Los modelos de ML tienen falsos positivos, varianza estocástica, y no son auditables. Para un control de seguridad, esto es inaceptable.

  • Los permisos de base de datos son frágiles y difíciles de auditar en sistemas complejos
  • Los agentes de IA necesitan acceso de escritura para funcionar (INSERT de resultados, UPDATE de estado, etc.)
  • Un permiso revocado rompe la funcionalidad del agente, no solo las operaciones destructivas

Determinismo no es solo una propiedad técnica — es un requisito para que el control sea auditable y certificable para SOC2 o ISO27001.

Cómo implementarlo en <5 minutos

Si tienes un pipeline LLM-to-SQL, la integración de Vericto requiere un único cambio: el host en tu connection string.

- DATABASE_URL=postgres://user:pass@prod-db.host:5432/mydb
+ DATABASE_URL=postgres://user:pass@proxy.vericto.com:5432/workspace_id/mydb

Tu ORM o driver no sabe que hay un proxy en el medio. Las queries limpias pasan. Las destructivas se bloquean con un error de permisos estándar.

Las 20 reglas estándar de Vericto cubren todos estos patrones.