42 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

Lo que agrega el proxy está medido, con sus condiciones, en Latencia medida: 0,42 ms en p50 en PostgreSQL con 1 conexión (staging, 16 de octubre de 2026). Es una medición, no una garantía.

Cobertura por familia de incidente

42 reglas · 6 dialectos · 8 familias de incidentes · 52 escenarios. Un escenario es un patrón concreto de SQL que una regla detecta, con un ejemplo que pasamos por vericto-engine 4.1.1 (las 42 reglas estándar y la política por defecto) el 16 de octubre de 2026.

Cómo se cuenta: un patrón es un escenario una sola vez, aunque se detecte en varios dialectos o en varias posiciones de la sentencia. Cada escenario tiene una familia y un origen principales, así que las sumas por familia y por origen dan el total. Los límites del motor que no son reglas (anidamiento y tamaño) no se cuentan. Dos escenarios necesitan configuración: VERICTO-085 (columnas sensibles) y VERICTO-087 (allowlists de agentes).

El filtro también se aplica a las tablas de reglas de esta página.

FamiliaEscenariosReglas
Borrado o reescritura masiva de datos10001 003 011 030 031 033 040 042 083 094
Destrucción del esquema7010 012 013 015 016 094
Protecciones desactivadas6017 019 099
Exfiltración y fuga de datos10040 082 084 085 087 091 092 093 098 100 101
Ejecución de código y escalada de privilegios6080 081 082 096 097 100
Inyección y evasión4010 012 070 086 090
Rendimiento y costo5050 051 061 095
Recuperación y calidad de datos4002 018 060 094

Escenarios por origen

La misma regla frena el error de una persona, el bug de un ORM y el ataque de un agente comprometido. Cada escenario se cuenta en su origen más típico:

OrigenEscenarios
Consola de un desarrollador o DBA5
Bug de la aplicación o del ORM7
Migración en CI/CD9
Agente de IA o text-to-SQL9
Atacante por SQL injection9
Insider o agente comprometido13

Los 52 escenarios

IDEscenarioReglasAcción por defectoDialectosOrigen
S01 DELETE sin WHERE VERICTO-001 block Los 6 Agente de IA o text-to-SQL
S02 DELETE con un WHERE siempre verdadero (1=1, id = id, '1abc' en SQLite) VERICTO-003 block Los 6 Agente de IA o text-to-SQL
S03 UPDATE sin WHERE VERICTO-030 VERICTO-042 block Los 6 Consola de un desarrollador o DBA
S04 UPDATE con un WHERE siempre verdadero (un query builder con el filtro vacío) VERICTO-030 VERICTO-042 block Los 6 Bug de la aplicación o del ORM
S05 UPDATE sin WHERE dentro de un CTE que modifica datos VERICTO-031 VERICTO-030 VERICTO-042 block PostgreSQL Agente de IA o text-to-SQL
S06 DELETE sin WHERE escondido en un CTE bajo un SELECT VERICTO-001 VERICTO-033 block PostgreSQL Insider o agente comprometido
S07 DELETE o UPDATE masivo en el cuerpo de un trigger, que corre en cada escritura VERICTO-001 VERICTO-003 VERICTO-030 block SQLite Migración en CI/CD
S08 TRUNCATE VERICTO-011 block PostgreSQL, MySQL, Oracle, SQL Server, Snowflake Consola de un desarrollador o DBA
S09 MERGE que puede afectar todas las filas (todo MERGE se bloquea por defecto) VERICTO-083 block PostgreSQL, Oracle, SQL Server, Snowflake Bug de la aplicación o del ORM
S10 INSERT OVERWRITE de Snowflake reemplaza todas las filas VERICTO-094 VERICTO-040 block Snowflake Migración en CI/CD
S11 DROP TABLE VERICTO-010 block Los 6 Agente de IA o text-to-SQL
S12 DROP DATABASE VERICTO-010 block PostgreSQL, MySQL, Oracle, SQL Server, Snowflake Consola de un desarrollador o DBA
S13 DROP SCHEMA … CASCADE (un "reset" del ORM) VERICTO-012 block PostgreSQL, MySQL, Oracle, SQL Server, Snowflake Migración en CI/CD
S14 ALTER TABLE … DROP COLUMN (un push del esquema) VERICTO-015 block Los 6 Migración en CI/CD
S15 Renombrar una tabla o columna (también SWAP WITH en Snowflake) VERICTO-016 block Los 6 Migración en CI/CD
S16 DROP INDEX sin IF EXISTS VERICTO-013 block Los 6 Migración en CI/CD
S17 CREATE OR REPLACE de Snowflake borra la tabla, el esquema o la base existente VERICTO-094 block Snowflake Agente de IA o text-to-SQL
S18 Desactivar row-level security VERICTO-019 block PostgreSQL Insider o agente comprometido
S19 Desactivar los triggers de una tabla (incluidos los de auditoría) VERICTO-019 block PostgreSQL Consola de un desarrollador o DBA
S20 DROP TRIGGER VERICTO-019 block PostgreSQL, MySQL, Oracle, SQL Server, SQLite Migración en CI/CD
S21 Eliminar una foreign key, primary key o restricción CHECK VERICTO-017 block PostgreSQL, MySQL, Oracle, SQL Server, Snowflake Migración en CI/CD
S22 Snowflake: quitar una row access policy o una masking policy VERICTO-019 block Snowflake Insider o agente comprometido
S23 PRAGMA de SQLite que apaga una protección (writable_schema, foreign_keys = OFF, journal_mode = OFF …) VERICTO-099 block SQLite Bug de la aplicación o del ORM
S24 INSERT … SELECT copia una tabla completa a un lugar legible VERICTO-040 block Los 6 Atacante por SQL injection
S25 Copia masiva con CREATE TABLE AS SELECT (también CLONE en Snowflake) VERICTO-084 block PostgreSQL, Snowflake, SQLite Insider o agente comprometido
S26 Lectura de una columna que marcaste como sensible (bloquear, enmascarar o marcar) requiere configuración VERICTO-085 según la etiqueta Los 6 Agente de IA o text-to-SQL
S27 Un agente toca una tabla o columna fuera de su allowlist requiere configuración VERICTO-087 block (enforce) / flag (observe) Los 6 Insider o agente comprometido
S28 Descarga de Snowflake a un stage o ubicación externa, GET, PUT VERICTO-091 block Snowflake Insider o agente comprometido
S29 Stage externo, integración o función externa de Snowflake VERICTO-092 block Snowflake Insider o agente comprometido
S30 Compartir con otra cuenta de Snowflake VERICTO-093 VERICTO-082 block Snowflake Insider o agente comprometido
S31 ATTACH DATABASE de SQLite abre o crea otro archivo VERICTO-098 block SQLite Atacante por SQL injection
S32 VACUUM INTO de SQLite escribe una copia completa de la base VERICTO-101 block SQLite Insider o agente comprometido
S33 readfile(), writefile() o edit() de SQLite: el sistema de archivos desde SQL VERICTO-100 block SQLite Atacante por SQL injection
S34 COPY … TO/FROM PROGRAM ejecuta un comando de shell en el host de la base VERICTO-080 block PostgreSQL Atacante por SQL injection
S35 Bloque de código anónimo que esconde sentencias (DO, EXECUTE IMMEDIATE o scripting de Snowflake) VERICTO-081 block PostgreSQL, Snowflake Agente de IA o text-to-SQL
S36 GRANT o REVOKE VERICTO-082 block PostgreSQL, MySQL, Oracle, SQL Server, Snowflake Insider o agente comprometido
S37 Cambio a un rol administrativo en Snowflake VERICTO-097 block Snowflake Insider o agente comprometido
S38 Código de Snowflake que corre después, fuera de todo control (task, procedure, stream, pipe, alert) VERICTO-096 block Snowflake Insider o agente comprometido
S39 load_extension() o fts3_tokenizer() de SQLite: código nativo VERICTO-100 block SQLite Atacante por SQL injection
S40 Tautología OR en un WHERE (' OR 1=1) VERICTO-090 block Los 6 Atacante por SQL injection
S41 Sonda ciega por tiempo (pg_sleep, SLEEP, system$wait, randomblob de SQLite) VERICTO-070 block Los 6 Atacante por SQL injection
S42 Sentencia apilada después de un envoltorio read-only (COMMIT; DROP …) VERICTO-012 VERICTO-010 block Los 6 Atacante por SQL injection
S43 Comentario ejecutable o escape de MySQL que el motor no puede resolver a una sola sentencia VERICTO-086 block MySQL Atacante por SQL injection
S44 SELECT sin límite (sin LIMIT, FETCH ni TOP) VERICTO-050 flag Los 6 Agente de IA o text-to-SQL
S45 SELECT * sin WHERE VERICTO-051 flag Los 6 Bug de la aplicación o del ORM
S46 Lote de INSERT de más de 10.000 filas VERICTO-061 flag Los 6 Bug de la aplicación o del ORM
S47 COPY FROM un archivo del servidor de la base VERICTO-061 flag PostgreSQL Consola de un desarrollador o DBA
S48 Warehouse de Snowflake agrandado o sin auto-suspensión VERICTO-095 block Snowflake Agente de IA o text-to-SQL
S49 Cambio de tipo de columna con pérdida o bloqueante VERICTO-018 block PostgreSQL, Snowflake Migración en CI/CD
S50 INSERT sin lista de columnas VERICTO-060 monitor Los 6 Bug de la aplicación o del ORM
S51 DELETE … LIMIT 0 (un alcance mal configurado) VERICTO-002 block MySQL, SQLite Bug de la aplicación o del ORM
S52 Recuperación reducida en Snowflake (retención 0, UNDROP, ALTER ACCOUNT) VERICTO-094 block Snowflake Insider o agente comprometido

Dónde se detecta

Las reglas se evalúan sobre cada sentencia que el motor encuentra, no solo sobre la de arriba: los CTEs (y los CTEs que modifican datos, en PostgreSQL), las tablas derivadas y las subqueries de un JOIN, las subqueries escalares de la proyección, las ramas UNION, la fuente de un INSERT … SELECT, cada sentencia de un string multi-sentencia, el cuerpo de un trigger de SQLite y el de un bloque de scripting de Snowflake. PostgreSQL y SQLite leen además las subqueries IN y EXISTS del WHERE de un SELECT, y SQLite lee cada cláusula. VERICTO-050 es la excepción a propósito: solo mira la query que recibe el cliente.

Un DELETE escondido en un CTE, una tautología en una tabla derivada o en una rama UNION, un DROP apilado después de un COMMIT, un INSERT … SELECT dentro de un trigger de SQLite: el motor recorre el árbol sintáctico hasta 50 niveles y evalúa cada sentencia de un string multi-sentencia. Lo que es más profundo, o lo que el parser no puede leer, no pasa en silencio: queda registrado como error de parseo, y se bloquea si eliges parse_error: block.

Unos 950 NOT encadenados, unos 4 KB de SQL, desbordan la pila de un parser recursivo y matan el proceso que lo ejecuta. Vericto mide el anidamiento del texto antes de parsearlo y rechaza lo que pasa de 200 niveles: el proxy sigue en pie y la sentencia queda registrada como demasiado compleja (bloqueada con parse_error: block).

Lo que vericto-engine 4.1.1 todavía no lee

  • En MySQL, Oracle, SQL Server y Snowflake, una tautología, un sleep o un SELECT * dentro de una subquery IN o EXISTS del WHERE (PostgreSQL y SQLite sí la leen).
  • Una subquery dentro del WHERE de un UPDATE o un DELETE: solo se lee en SQLite.
  • Fuera de SQLite, un sleep dentro de IS NULL, CASE, ORDER BY o UPDATE … SET (en la proyección, en una comparación del WHERE, en CTEs y en tablas derivadas sí se detecta).
  • VERICTO-084 no reporta CREATE TABLE … SELECT de MySQL ni de Oracle, ni SELECT … INTO de PostgreSQL y SQL Server; VERICTO-018 no reporta MODIFY ni CHANGE COLUMN de MySQL.
  • Las formas nativas que el parser no lee (GRANT CONTROL de SQL Server, privilegios de sistema de Oracle, DISABLE TRIGGER de SQL Server) son errores de parseo: se reenvían y se registran por defecto, y se bloquean con parse_error: block.

En 6 incidentes públicos que documentamos, el SQL destructivo (el publicado, o la sentencia que implica el mecanismo) da BLOCKED con estas reglas cuando la conexión pasa por Vericto: un DELETE FROM en cada tabla de producción, DROP TABLE pedido a frameworks de text-to-SQL (dos CVE), un schema push que borró tablas, COPY … TO PROGRAM en un servidor MCP «read-only» y un COMMIT; DROP SCHEMA que escapó de una transacción de solo lectura. Los casos, con sus fuentes.

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 salvo SQLite DELETE FROM {tabla} WHERE created_at < NOW() - INTERVAL '90 days'
VERICTO-012 DROP SCHEMA DropStmt > ObjectType = SCHEMA Todos salvo SQLite 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 salvo SQLite 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 Postgres, Snowflake 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 Postgres (DISABLE TRIGGER, RLS), Snowflake (políticas); DROP TRIGGER en todos salvo Snowflake 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 Postgres 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 salvo SQLite Gestiona privilegios mediante migraciones de permisos revisadas, no desde queries de aplicación
VERICTO-083 MERGE MergeStmt Postgres, Oracle, SQL Server, Snowflake 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 Postgres, Snowflake, SQLite 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
VERICTO-087 Acceso fuera de la allowlist del agente Cualquier referencia (proyección, predicado, subquery, destino de escritura) que la allowlist de la identidad no concede, o DDL Todos La decide la allowlist del agente: en enforce bloquea, en observe marca

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 Qué no dispara la regla
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 los SDK de Python y Node, la API de runtime, la CLI en CI/CD y MCP (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>.

Latencia medida, con sus condiciones

Medido en staging el 16 de octubre de 2026: vericto-proxy 4.12.0 en una tarea Fargate ARM64 de 0,25 vCPU y 512 MB, Aurora Serverless v2 precalentada a 10 ACU (PostgreSQL 16.9 y MySQL 8.0.39), TLS en los dos tramos, modo enforce con el catálogo estándar y una mezcla tipo ORM de sentencias legítimas pequeñas: lookups por clave, joins, listas IN, UPDATE e INSERT de una fila, transacciones y sentencias marcadas y bloqueadas. La ruta directa a la base se midió en la misma corrida, con 3 repeticiones por celda.

  • Latencia agregada en p50 (proxy menos directo): PostgreSQL 0,42 ms con 1 conexión, 0,50 ms con 4 y 0,86 ms con 16 (unas 2.000 sentencias/s); MySQL de 0,34 a 0,36 ms con 1 a 32 conexiones.
  • Agregado en p99, sin saturar el proxy: PostgreSQL 0,51 ms con 1 conexión; MySQL 1,9 ms o menos con 1 y 4 conexiones. Como referencia, por la ruta directa un lookup por clave tarda 0,28 ms en p50.
  • Capacidad: una instancia de 0,25 vCPU procesó unas 2.000 sentencias/s de PostgreSQL antes de saturar su CPU; por encima de eso, la cola crece dentro del proxy. Para más tráfico, más CPU o más instancias detrás del balanceador (esto último no se midió aquí).
  • Tamaño de la sentencia: lo agregado crece con el tamaño. En PostgreSQL, un INSERT de 10 filas agrega 0,58 ms en p50; de 100 filas, 1,05 ms; de 500, 3,07 ms; de 1.000, 5,54 ms.
  • Solo la evaluación de reglas, sin red: p99 de 100 µs o menos para las sentencias OLTP (vericto-engine 3.9.0 en 0,25 vCPU ARM64).
  • Telemetría: 0 eventos perdidos de los 1.222.254 enviados al plano de control durante la sesión.

Es una medición en esas condiciones, no una garantía: tu red, el tamaño de la instancia y tus sentencias cambian el resultado. El modo observe y las columnas enmascaradas no se midieron en esta sesión.

Í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-087Acceso fuera de la allowlist del agenteHIGHBLOCK (ENFORCE) / FLAG (OBSERVE)
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