30 reglas. Ninguna usa ML.

Todas las reglas estándar de Vericto y cómo configurarlas.

Cómo funcionan las reglas

Cuando una query llega al proxy de Vericto, el parser construye el AST (Abstract Syntax Tree) completo de la query. El engine recorre el árbol en profundidad buscando nodos que violen las condiciones definidas en cada regla activa.

El proceso es siempre el mismo:

  1. La query SQL llega al proxy como texto plano
  2. El engine selecciona el parser correcto según el dialecto (pg_query para Postgres, sqlparser-rs para MySQL, Oracle, SQL Server, Snowflake y SQLite). PostgreSQL y MySQL pueden evaluarse por el proxy TCP; Oracle, SQL Server, Snowflake y SQLite, por la API HTTP
  3. El AST completo se construye en memoria
  4. El engine evalúa cada regla activa contra el árbol
  5. Si alguna regla se viola, la query es bloqueada antes de llegar a la base de datos

Cada regla define exactamente cinco propiedades:

  • Código: identificador único en formato VERICTO-XXX o CUSTOM-XXX
  • Condición AST: el nodo y la propiedad que se evalúa (ej: DeleteStmt > WhereClause = NULL)
  • Dialecto(s): uno o varios dialectos SQL donde aplica la regla
  • Severidad: uno de los 5 niveles CVSS — CRITICAL, HIGH, MEDIUM, LOW o INFORMATIONAL
  • Query segura sugerida: la versión corregida de la query que se muestra en el log de bloqueo

El parsing AST añade en promedio menos de 0.4ms al tiempo de respuesta. El p99 total del proxy (parsing + evaluación de reglas + overhead de red) es inferior a 2ms.

Niveles de severidad

Vericto usa la taxonomía CVSS de 5 niveles. La acción por defecto se puede personalizar por workspace con una EnforcementPolicy.

Severidad Acción por defecto Comportamiento Alertas
CRITICAL BLOCK Bloqueo inmediato de la query. SQLSTATE 42501 al cliente. Alerta en tiempo real via webhook y dashboard
HIGH BLOCK Bloqueo de la query, registro completo en el audit trail. Alerta en tiempo real
MEDIUM FLAG La query se reenvía al upstream. Se registra y genera alerta pero no bloquea. Alerta (FLAG) en dashboard y webhook
LOW MONITOR La query se reenvía. Solo se registra en telemetría, sin alerta. Solo telemetría / audit trail
INFORMATIONAL MONITOR La query se reenvía. Registro informativo, sin acción. Solo métricas

En todos los planes, el owner y los admins del workspace pueden personalizar la EnforcementPolicy (cambiar la acción por severidad o activar el modo observación). Es útil durante la adopción para observar el tráfico antes de activar bloqueos.

Reglas CRITICAL

Las reglas CRITICAL detectan operaciones que pueden causar pérdida irreversible de datos masivos. Se activan en todos los dialectos soportados salvo indicación contraria.

Código Nombre Condición AST Dialectos Query segura sugerida
VERICTO-001 DELETE sin WHERE DeleteStmt > WhereClause = NULL Todos DELETE FROM {tabla} WHERE id = $1
VERICTO-003 DELETE con WHERE siempre verdadero DeleteStmt > WhereClause = ALWAYS_TRUE (1=1, true) Todos DELETE FROM {tabla} WHERE id = $1
VERICTO-010 DROP TABLE / DROP DATABASE DropStmt (excluye DROP INDEX) Todos Usa migraciones versionadas (Flyway, Prisma Migrate, Alembic)
VERICTO-011 TRUNCATE TABLE TruncateStmt (nodo presente) Todos DELETE FROM {tabla} WHERE created_at < NOW() - INTERVAL '90 days'
VERICTO-012 DROP SCHEMA DropStmt > ObjectType = SCHEMA Todos Usa migraciones versionadas
VERICTO-030 UPDATE sin WHERE (tablas principales) UpdateStmt > WhereClause != Present Todos UPDATE {tabla} SET {col} = $1 WHERE id = $2
VERICTO-042 UPDATE sin cláusula WHERE UpdateStmt > WhereClause = NULL (incluye WHERE trivial) Todos UPDATE {tabla} SET {col} = $1 WHERE id = $2
VERICTO-080 COPY … TO/FROM PROGRAM CopyStmt > program = true Postgres Usa COPY … TO/FROM STDIN o rutas de archivo controladas; nunca ejecutes comandos de shell desde SQL
VERICTO-081 Bloque de código anónimo DO DoStmt (DO $$ … $$) Postgres Mueve la lógica a una función/migración revisada en lugar de un bloque anónimo opaco al parser
VERICTO-086 Texto SQL que MySQL y el motor leerían distinto Texto que no se puede resolver con certeza a una sola sentencia por cómo MySQL lee sus comentarios y escapes de string MySQL Siempre activa: no se desactiva ni se baja de severidad. Envía SQL sin comentarios ni escapes ambiguos

Reglas HIGH

Las reglas HIGH detectan operaciones de alto riesgo que pueden causar pérdida parcial de datos o cambios estructurales irreversibles.

Código Nombre Condición AST Dialectos Query segura sugerida
VERICTO-002 DELETE con LIMIT 0 DeleteStmt > LimitCount = 0 MySQL, SQLite DELETE FROM {tabla} WHERE id = $1 LIMIT 1
VERICTO-013 DROP INDEX sin IF EXISTS DropStmt > ObjectType = INDEX & IF_EXISTS = false Todos DROP INDEX IF EXISTS {index_name}
VERICTO-015 ALTER TABLE DROP COLUMN AlterTableStmt > AlterTableCmd.subtype = DROP_COLUMN Todos Usa soft-delete con columna deleted_at o migración versionada
VERICTO-016 ALTER TABLE RENAME AlterTableStmt > Rename Todos Usa herramienta de migración y actualiza todas las referencias primero
VERICTO-017 ALTER TABLE DROP CONSTRAINT AlterTableStmt > DropConstraint (FK/PK/CHECK, DROP PRIMARY KEY) Todos Elimina la restricción solo en una migración revisada, tras confirmar que ningún dato ni código depende de ella
VERICTO-018 ALTER TABLE ALTER COLUMN TYPE AlterTableStmt > AlterColumnType Todos Haz el cambio de tipo en una migración por fases (columna nueva + backfill) para evitar reescritura bloqueante o cast con pérdida
VERICTO-019 ALTER TABLE DISABLE TRIGGER / RLS AlterTableStmt > DisableTrigger | DisableRowSecurity Todos No desactives triggers ni Row Level Security en producción; si es imprescindible, hazlo en una ventana controlada y reactívalos de inmediato
VERICTO-031 UPDATE sin WHERE anidado en CTE WithClause > UpdateStmt > WhereClause = NULL Postgres Agregar WHERE con predicado específico al UPDATE dentro del CTE
VERICTO-033 DELETE sin WHERE en subquery/CTE WithClause/SubLink > DeleteStmt > WhereClause = NULL Todos Reescribir como DELETE con JOIN y WHERE explícitos
VERICTO-040 INSERT INTO … SELECT sin filtro InsertStmt > source = SelectStmt Todos INSERT INTO {tabla} SELECT ... WHERE <condición> LIMIT N
VERICTO-070 Uso de SLEEP() o PG_SLEEP() FunctionCall > name = sleep|pg_sleep Todos Eliminar la llamada a SLEEP del pipeline
VERICTO-082 GRANT / REVOKE GrantStmt (GRANT o REVOKE) Todos Gestiona privilegios mediante migraciones de permisos revisadas, no desde queries de aplicación
VERICTO-083 MERGE MergeStmt Todos Acota el MERGE con condiciones específicas; puede mutar en masa como un UPDATE/DELETE sin WHERE efectivo
VERICTO-084 CREATE TABLE AS SELECT CreateTableAsStmt / SELECT … INTO Todos Añade un WHERE/LIMIT a la fuente para no duplicar una tabla completa
VERICTO-085 Lectura de una columna sensible Proyección que deriva de una columna marcada (SELECT, RETURNING, COPY … TO) Todos La deciden las columnas sensibles de cada base: lista las columnas en lugar de SELECT * y no proyectes las marcadas

Reglas MEDIUM

Las reglas MEDIUM detectan patrones de queries que pueden indicar un agente de IA operando sin contexto adecuado, o que podrían degradar el rendimiento de la base de datos.

Código Nombre Condición AST Dialectos Query segura sugerida
VERICTO-050 SELECT sin LIMIT SelectStmt > LimitCount = NULL Todos SELECT ... WHERE <condición> LIMIT 1000
VERICTO-051 SELECT * sin WHERE SelectStmt > TargetEntry = STAR & WhereClause = NULL Todos SELECT col1, col2 FROM ... WHERE <condición>
VERICTO-060 INSERT sin columnas explícitas InsertStmt > Cols = NULL Todos INSERT INTO {tabla} (col1, col2) VALUES ($1, $2)
VERICTO-061 INSERT batch con más de 10k filas InsertStmt > ValuesList count > 10000 Todos Dividir en lotes de ≤1,000 filas con múltiples INSERT o COPY

Reglas de SQL Injection

Detección determinística de patrones de SQL injection en queries generadas por LLMs. A diferencia de los WAFs tradicionales basados en patrones de texto, Vericto analiza el AST, lo que hace que la detección sea inmune a ofuscaciones que preservan la semántica.

Código Nombre Condición AST Dialectos Por qué no genera falsos positivos
VERICTO-090 Tautología OR en WHERE WhereClause > BoolExpr(OR) > always_true_branch Todos Un LLM generando queries legítimas nunca tiene razón para incluir OR 1=1. Solo existen en intentos de bypass de autenticación.

Cobertura de VERICTO-090: aplica a las cláusulas WHERE de SELECT, DELETE y UPDATE. Detecta patrones como OR 1=1, OR 'a'='a', OR true, y tautologías anidadas como AND (condición OR 1=1).

Reglas de Snowflake

Siete reglas para Snowflake (vericto-engine 4.0.0). Solo leen lo que registra el parser de Snowflake, así que nunca se disparan en otro dialecto. Snowflake no tiene proxy TCP: estas reglas se aplican en la API HTTP, la CLI en CI/CD y MCP.

Código Nombre Condición AST Dialectos Query segura sugerida
VERICTO-091 Descarga a un stage o transferencia de archivos COPY INTO @stage | 's3://…' | 'azure://…' | 'gcs://…', GET, PUT Snowflake Carga desde el stage (COPY INTO tabla FROM @stage); las descargas de datos van por un proceso revisado fuera de la aplicación
VERICTO-092 Stage externo o integración CREATE|ALTER STAGE … URL = | CREDENTIALS, CREATE STORAGE | EXTERNAL ACCESS | API INTEGRATION, CREATE EXTERNAL FUNCTION Snowflake Usa un stage interno; las integraciones y los stages externos se crean en migraciones revisadas
VERICTO-093 Compartir con otra cuenta GRANT … TO SHARE, CREATE SHARE, ALTER SHARE … ADD | SET ACCOUNTS, CREATE LISTING Snowflake Compartir datos es una decisión de la cuenta: tómala fuera del SQL de la aplicación
VERICTO-094 Recuperación reducida DATA_RETENTION_TIME_IN_DAYS = 0, CREATE OR REPLACE TABLE | SCHEMA | DATABASE, INSERT OVERWRITE, UNDROP, ALTER ACCOUNT Snowflake CREATE TABLE IF NOT EXISTS y una retención mayor que 0; en CI se marca (flag) como un DROP TABLE
VERICTO-095 Costo de warehouse CREATE|ALTER WAREHOUSE … WAREHOUSE_SIZE | MAX_CLUSTER_COUNT | AUTO_SUSPEND = 0, ALTER RESOURCE MONITOR Snowflake Crea el warehouse con los valores por defecto o con AUTO_SUSPEND mayor que 0; el tamaño se cambia en una migración revisada
VERICTO-096 Código que se ejecuta después CREATE TASK | STREAM | PIPE | PROCEDURE | FUNCTION | ALERT, ALTER TASK … RESUME | MODIFY AS, EXECUTE TASK Snowflake Crea tareas y procedimientos en migraciones revisadas; desde la aplicación, llámalos con CALL
VERICTO-097 Cambio de rol USE ROLE, USE SECONDARY ROLES ALL | <roles> Snowflake Conéctate con el rol que la aplicación necesita; USE SECONDARY ROLES NONE no se reporta

Reglas de SQLite

Cuatro reglas para SQLite (vericto-engine 4.1.0). Solo leen lo que registra el parser de SQLite, así que nunca se disparan en otro dialecto. SQLite es una biblioteca dentro de tu aplicación, sin servidor ni protocolo de red, así que no hay proxy TCP: estas reglas se aplican en la API de runtime, la CLI en CI/CD y MCP; los SDK de Python y Node llegan próximamente (SQLite).

Código Nombre Condición AST Dialectos Query segura sugerida
VERICTO-098 ATTACH DATABASE en SQLite ATTACH [DATABASE] <archivo> AS <nombre> SQLite No adjuntes archivos desde la aplicación; abre cada base con su propia conexión. DETACH no se reporta
VERICTO-099 PRAGMA que desactiva una protección PRAGMA writable_schema | trusted_schema = ON | foreign_keys = OFF | ignore_check_constraints = ON | journal_mode = OFF | synchronous = OFF | cell_size_check = OFF | query_only = OFF | schema_version = n | temp_store_directory SQLite Lecturas (PRAGMA table_info(t)) y ajustes seguros (foreign_keys = ON, journal_mode = WAL) no se reportan; en CI se marca (flag) como un DROP TABLE
VERICTO-100 Carga de extensiones o funciones de archivos load_extension(), fts3_tokenizer(), readfile(), writefile(), edit(), fsdir(), zipfile() en cualquier cláusula SQLite Carga las extensiones al abrir la conexión, desde el código de la aplicación, nunca desde SQL
VERICTO-101 VACUUM INTO en SQLite VACUUM [esquema] INTO <archivo> SQLite Un VACUUM simple no se reporta; las copias de seguridad van por un proceso revisado (la API de backup de SQLite)

Las reglas estándar en SQLite

  • Se aplican tal cual (15): VERICTO-001, 002 (DELETE … LIMIT 0, en builds con SQLITE_ENABLE_UPDATE_DELETE_LIMIT), 010, 013, 015, 016, 019 (DROP TRIGGER; SQLite no tiene DISABLE TRIGGER ni RLS), 030, 040, 042, 050, 051, 060, 061 (lotes de más de 10.000 filas; no hay COPY) y 084 (CREATE TABLE … AS SELECT).
  • Con una variante para SQLite (5): 003 y 090 (en SQLite un string con prefijo numérico distinto de cero, como WHERE '1abc', es verdadero; también como nombre entre comillas dobles, "1", por DQS), 070 (SQLite no tiene sleep: se detecta randomblob(N) o zeroblob(N) con un N constante de 10.000.000 bytes o más, la sonda de inyección por tiempo), 085 (las máscaras de SQLite; hash bloquea) y 087 (nombres sin distinguir mayúsculas, esquema main por defecto).
  • No se aplican, nunca se disparan en SQLite (11): 011 (TRUNCATE), 012 (DROP SCHEMA), 017 (DROP CONSTRAINT), 018 (ALTER COLUMN … TYPE), 031 y 033 (SQLite no tiene CTEs que modifiquen datos), 080 (COPY … PROGRAM), 081 (bloques DO), 082 (GRANT/REVOKE), 083 (MERGE) y 086 (la ambigüedad léxica de MySQL). SQLite rechaza esas sentencias.

Reglas custom (YAML)

Los planes Builder y superiores permiten definir reglas personalizadas en YAML. Puedes crear reglas que bloqueen operaciones específicas en tablas concretas, sin tocar el código de tu aplicación.

Las reglas custom se evalúan después de las reglas built-in con la misma latencia. El YAML tiene node_type en el nivel superior y los predicados dentro de condition:

rule: block-update-on-payments
node_type: UpdateStmt
condition:
  relation: payments

Los predicados de condition son ocho: relation, where_clause, where_always_true, target_list, has_limit, func_name, object_type y alter_kind. El nombre, la severidad y el dialecto no van en el YAML: son campos del formulario y de la API.

La referencia completa —los ocho tipos de nodo, los ocho predicados y ejemplos listos para copiar— está en la documentación de reglas custom.

Las reglas custom se cargan en caliente sin reiniciar el proxy. El tiempo de propagación es inferior a 5 segundos desde que guardas el archivo en el dashboard.

Las reglas custom se gestionan desde el dashboard del workspace. Desde el CLI puedes inspeccionar el catálogo efectivo con vericto rules list y ver el detalle de una regla con vericto rules show <CÓDIGO>.

Índice de códigos

Código Descripción Severidad Acción por defecto
VERICTO-001DELETE sin cláusula WHERECRITICALBLOCK
VERICTO-002DELETE con LIMIT 0 (MySQL, SQLite)HIGHBLOCK
VERICTO-003DELETE con WHERE siempre verdadero (1=1, true)CRITICALBLOCK
VERICTO-010DROP TABLE o DROP DATABASECRITICALBLOCK
VERICTO-011TRUNCATE TABLECRITICALBLOCK
VERICTO-012DROP SCHEMACRITICALBLOCK
VERICTO-013DROP INDEX sin IF EXISTSHIGHBLOCK
VERICTO-015ALTER TABLE DROP COLUMNHIGHBLOCK
VERICTO-016ALTER TABLE RENAME (tabla o columna)HIGHBLOCK
VERICTO-017ALTER TABLE DROP CONSTRAINT (FK/PK/CHECK)HIGHBLOCK
VERICTO-018ALTER TABLE ALTER COLUMN TYPEHIGHBLOCK
VERICTO-019ALTER TABLE DISABLE TRIGGER / RLSHIGHBLOCK
VERICTO-030UPDATE sin WHERE en tabla principalCRITICALBLOCK
VERICTO-031UPDATE sin WHERE dentro de CTEHIGHBLOCK
VERICTO-033DELETE sin WHERE en subquery o CTEHIGHBLOCK
VERICTO-040INSERT INTO … SELECT sin filtroHIGHBLOCK
VERICTO-042UPDATE sin cláusula WHERECRITICALBLOCK
VERICTO-050SELECT sin LIMITMEDIUMFLAG
VERICTO-051SELECT * sin cláusula WHEREMEDIUMFLAG
VERICTO-060INSERT sin columnas explícitasLOWMONITOR
VERICTO-061INSERT batch con más de 10k filasMEDIUMFLAG
VERICTO-070Uso de SLEEP() o PG_SLEEP()HIGHBLOCK
VERICTO-080COPY … TO/FROM PROGRAM (ejecución de shell)CRITICALBLOCK
VERICTO-081Bloque de código anónimo DOCRITICALBLOCK
VERICTO-082GRANT / REVOKEHIGHBLOCK
VERICTO-083MERGEHIGHBLOCK
VERICTO-084CREATE TABLE AS SELECTHIGHBLOCK
VERICTO-085Lectura de una columna sensibleHIGHSEGÚN LA ETIQUETA
VERICTO-086Texto SQL que MySQL y el motor leerían distinto (MySQL)CRITICALBLOCK
VERICTO-090SQL injection: tautología OR en WHERE (OR 1=1)CRITICALBLOCK
VERICTO-091Descarga a un stage o transferencia de archivos (Snowflake)CRITICALBLOCK
VERICTO-092Stage externo o integración (Snowflake)CRITICALBLOCK
VERICTO-093Compartir con otra cuenta (Snowflake)CRITICALBLOCK
VERICTO-094Recuperación reducida (Snowflake)HIGHBLOCK
VERICTO-095Costo de warehouse (Snowflake)HIGHBLOCK
VERICTO-096Código que se ejecuta después (Snowflake)HIGHBLOCK
VERICTO-097Cambio de rol (Snowflake)HIGHBLOCK
VERICTO-098ATTACH DATABASE (SQLite)HIGHBLOCK
VERICTO-099PRAGMA que desactiva una protección (SQLite)HIGHBLOCK
VERICTO-100Carga de extensiones o funciones de archivos (SQLite)CRITICALBLOCK
VERICTO-101VACUUM INTO (SQLite)HIGHBLOCK