Una cuenta de backup de PostgreSQL ahora puede ejecutar código en su servidor. Parchee CVE-2026-6471.

Postgres publicó una corrección el 13 de agosto para un error que llevaba en el código desde 2014. CVE-2026-6471 permite que cualquier cuenta con el atributo REPLICATION, el tipo de cuenta con bajos privilegios que usa su herramienta de backup o réplica de lectura, cargue una biblioteca compartida arbitraria en el proceso de base de datos y ejecute código como el usuario del sistema operativo que posee Postgres. El aviso oficial lo describe claramente: la decodificación lógica puede hacer dlopen de un archivo arbitrario, elegido por el cliente de replicación, sin ninguna verificación de autorización. Cyera Research, que lo reportó junto a Yu Kunpeng, lo llama PostGREShell.
Los mecanismos vale la pena entenderlos, porque explican la solución. Cuando un cliente de replicación abre un slot de decodificación lógica, nombra un plugin de salida, y Postgres carga ese plugin como código compilado dentro de su propio proceso. Para un LOAD SQL ordinario, Postgres restringe a los no superusuarios a un directorio de plugins controlado. La ruta de replicación omitía esa verificación, por lo que el nombre del plugin podía ser cualquier ruta en disco. En Windows es peor: el cargador acepta una ruta UNC, por lo que un atacante la apunta a una DLL en su propio recurso compartido SMB y nunca tiene que depositar un archivo en el objetivo primero.
Aquí está la parte que se perdió en algunas coberturas. El CVSS oficial es 7,2, alto pero no crítico, y la razón está justo ahí en el vector: PR:H. Necesita una cuenta que ya tenga REPLICATION. Este no es un agujero sin autenticación expuesto a internet abierto. ¿Por qué preocuparse entonces? Porque en sistemas reales esas cuentas están en todas partes y nadie las trata como peligrosas. Cada réplica de streaming, cada trabajo de backup, cada pipeline de captura de cambios de datos, cada agente de monitoreo que sigue el write-ahead log se ejecuta como un rol REPLICATION. Son la fontanería operacional, y la fontanería tiende a tener credenciales débiles, de larga duración y ampliamente copiadas.
Durante las revisiones de seguridad en la nube seguimos encontrando el mismo patrón: un usuario de replicación cuya contraseña vive en tres archivos env y una variable de Terraform, reutilizada entre staging y producción, accesible desde más partes de la red de lo que nadie pretendía. Por sí solo parece un hallazgo de baja severidad, una cuenta de servicio con demasiados privilegios. Este CVE convierte exactamente esa cuenta en ejecución remota de código en el host de la base de datos. La lección no es realmente sobre Postgres. Es que las credenciales de servicio «con bajos privilegios» se mantienen así solo hasta que alguien encuentra un primitivo que las eleva.
La solución es un nuevo parámetro de servidor, output_plugin_libraries, añadido por Jacob Champion. Es una lista de permitidos. Por defecto solo permite los dos plugins que vienen con Postgres, pgoutput y test_decoding, por lo que un cliente de replicación ya no puede nombrar una biblioteca arbitraria. Si usa un decodificador de terceros como decoderbufs (usuarios de Debezium, esto les incluye), tendrá que añadirlo explícitamente después de actualizar o la replicación lógica fallará. En la versión 17 y superiores, pg_upgrade --check rechaza continuar si la lista de permitidos del nuevo cluster no cubre los plugins que usan sus slots existentes. Ese es un guardia útil y un punto a tener en cuenta en la migración.
Qué hacer esta semana
- Parchee a 18.6, 17.11, 16.15, 15.19 o 14.24. Las ramas más antiguas superaron su fin de vida y no recibirán esta corrección, así que si está en la versión 13 o anterior, trátelo como una razón más para migrar.
- Audite quién tiene REPLICATION. Haga un inventario real, no una suposición. Cualquier cuenta humana con el atributo probablemente debería perderlo, y cada cuenta de servicio que lo conserve necesita un secreto rotado y único.
- Bloquee el tráfico SMB y NFS saliente desde sus hosts de base de datos. La ruta de DLL remota en Windows depende de que la base de datos alcance el recurso compartido de archivos de un atacante. Su servidor de Postgres no tiene razón para abrir conexiones SMB salientes, así que bloquéelas en el firewall.
- Si establece output_plugin_libraries manualmente, liste exactamente los decodificadores que usa y nada más.
Una cosa vale la pena revisar, y otra ignorar. La búsqueda de amenazas de Cyera encontró 114 plugins maliciosos de Postgres en VirusTotal: troyanos, mineros, shells inversas. Eso es un recordatorio de que la carga de plugins es un objetivo popular, pero ninguna de esas muestras se ha vinculado a la explotación de este CVE específico, así que no lo tome como prueba de que fue afectado. Vale la pena ignorar: el encuadre de «doce años sin parchear». La vulnerabilidad fue real durante mucho tiempo, pero explotarla sigue requiriendo una cuenta REPLICATION, y si las mantuvo bloqueadas, nunca estuvo tan expuesto como el titular sugiere.
Pasamos bastante tiempo donde el endurecimiento de bases de datos se encuentra con la política de red, desde stacks de PHP y Docker en AWS hasta las reglas de Cloudflare y firewall que deciden qué puede alcanzar un servidor comprometido. El patrón que atrapa a los equipos es casi siempre una cuenta interna con demasiada confianza más un egreso que nadie bloqueó. Si una credencial de replicación olvidada con una contraseña compartida suena como algo que vive en su infraestructura, hablemos.