
La vulnerabilidad de escritura fuera de límites encontrada en la búsqueda de texto completo de PostgreSQL (tsvector/tsquery), CVE-2026-14662, verificada ejecutando en paralelo con Docker la versión sin corregir (18.4) y la corregida (18.6), junto con el registro y los materiales de la presentación.
Este es un registro de cómo se observó realmente la diferencia de comportamiento al ejecutar simultáneamente en Docker la versión anterior al parche (18.4) y la posterior al parche (18.6) de la CVE-2026-14662, encontrada en los tipos de datos de búsqueda de texto completo (tsvector / tsquery) de PostgreSQL.
Está recopilado con fines de aprendizaje sobre seguridad e incluye también los materiales de la presentación.
| Elemento | Contenido |
|---|
| CVE | CVE-2026-14662 |
| Objetivo | tsvector / tsquery de PostgreSQL |
| Tipo | Tamaño de asignación insuficiente y escritura fuera de límites por desbordamiento de enteros |
| CVSS | 8.8 / 10.0 (High) |
| Fecha de publicación | 2026-08-13 |
| Versiones corregidas | 18.5, 17.11, 16.15, 15.19, 14.24 |
La cadena de debilidades tiene la siguiente forma.
CWE-190 (Desbordamiento de enteros) → CWE-131 (Cálculo incorrecto del tamaño del búfer) → CWE-787 (Escritura fuera de límites)
=Causa raíz =Impacto final
.
├── docs/
│ └── presentation.md Materiales de la presentación (explicación de la vulnerabilidad + explicación de CWE)
└── docker/
├── README.md Cómo usar el entorno de reproducción
├── docker-compose.yml
├── init/ SQL de inicialización común que se ejecuta en ambas versiones
├── test/ PoC y SQL de demostración
└── run.sh Inicio → ejecución del PoC → visualización de resultados
Si tienes Docker y Docker Compose, puedes reproducirlo solo con lo siguiente.
cd docker
./run.sh
Se levantarán los contenedores de 18.4 y 18.6, se cargará el mismo SQL de inicialización en ambos y se ejecutará el mismo PoC en los dos para mostrar los resultados lado a lado. Consulta docker/README.md para más detalles.
| Prueba | PostgreSQL 18.4 (antes del parche) | PostgreSQL 18.6 (después del parche) |
|---|---|---|
| Repetir la auto-combinación OR de tsquery | Éxito sin errores hasta 18 veces (final: 8.650.748 bytes) | ERROR: tsquery is too large en la 17.ª vez |
| Matriz de palabras con longitud total de 1.200.000 bytes | Tiene éxito | ERROR: string is too long for tsvector (1200000 bytes, max 1048575 bytes) |
| Una sola palabra de 3.000 bytes | Tiene éxito | ERROR: word is too long (3000 bytes, max 2046 bytes) |
Antes del parche, se aceptan sin generar ni un solo error los datos que superan el límite de la representación interna (MAXSTRPOS = 1.048.575, derivado del campo de bits de 20 bits).
Además, el motivo por el que 18.6 se detiene "justo en la 17.ª vez" se puede explicar mediante cálculos, y se ha confirmado que el valor teórico y el valor medido coinciden byte a byte (detalles en los materiales de la presentación).
Para verificar las diferencias se utilizó un clon del repositorio oficial de PostgreSQL, pero no se incluye en este repositorio debido a su gran tamaño (185 MB cada uno). Si lo necesitas, obténlo de la siguiente manera.
git clone --branch REL_18_4 --depth 1 https://github.com/postgres/postgres.git postgres-18.4
git clone --branch REL_18_6 --depth 1 https://github.com/postgres/postgres.git postgres-18.6
Los archivos que recibieron el parche son los siguientes tres.
src/backend/utils/adt/tsquery_util.csrc/backend/utils/adt/tsvector.csrc/backend/utils/adt/tsvector_op.c