Si corrés PostgreSQL sobre Kubernetes con CloudNativePG, tenés trabajo pendiente. El proyecto publicó las versiones 1.29.1 y 1.28.3 para tapar CVE-2026-44477, la primera vulnerabilidad con CVE asignado en la historia del operador y calificada como crítica con CVSS 9.4. El agujero está en un componente que casi nadie mira: el metrics exporter, el que expone las métricas de Prometheus. Y no es una fuga de datos menor: permite pasar de un usuario común de base de datos a ejecución de comandos en el sistema operativo del pod primario.
CVE-2026-44477 es una escalada de privilegios en el exportador de métricas de CloudNativePG, el operador de PostgreSQL para Kubernetes. El exportador se conectaba a la base como superusuario postgres y se degradaba con SET ROLE pg_monitor, pero session_user seguía siendo postgres. Eso permite recuperar el superusuario con RESET ROLE y ejecutar comandos del sistema operativo. Se corrige actualizando a 1.29.1 o 1.28.3.
¿Qué hace exactamente el metrics exporter y por qué es peligroso?

El metrics exporter es el proceso que CloudNativePG usa para publicar métricas de PostgreSQL hacia Prometheus (conexiones, replicación, tamaño de tablas, extensiones instaladas). Para leer esos datos necesita permisos amplios, así que se conectaba a la base a través del socket Unix local del pod como el superusuario postgres. Ahí nace el problema: un componente de solo lectura estaba corriendo con la identidad más poderosa del motor.
La intención del diseño original era correcta: bajar privilegios apenas conectado. El exportador ejecutaba SET ROLE pg_monitor para operar con un rol de monitoreo acotado. En teoría, cualquier consulta que corriera después lo haría con permisos mínimos. En la práctica, esa degradación era una ilusión.
¿Cómo funciona la cadena de explotación de CVE-2026-44477?
La cadena aprovecha una diferencia sutil de PostgreSQL: SET ROLE cambia current_user, pero no toca session_user. Como el exportador abrió la sesión como postgres, el session_user superusuario sigue latente. Según el aviso de seguridad de CloudNativePG, cualquier expresión SQL evaluada dentro del ciclo de scraping puede llamar a RESET ROLE para recuperar el superusuario real y, desde ahí, usar COPY ... TO PROGRAM para lanzar un subproceso a nivel del sistema operativo con el usuario postgres dentro del pod primario.
Los pasos, en orden:
- Punto de partida con superusuario latente. El exportador conecta como
postgrespor el socket local y haceSET ROLE pg_monitor.current_userbaja,session_userqueda enpostgres. - Inyección durante el scrape. El atacante logra que una expresión SQL suya se evalúe dentro de la sesión de métricas, cosa que ocurre en cada intervalo de scraping (del orden de los 30 segundos).
- Recuperación del privilegio. Un
RESET ROLEdevuelve al usuario efectivo apostgres, porque la sesión nunca dejó de ser de un superusuario. - Salto al sistema operativo. Con
COPY ... TO PROGRAMse ejecuta un comando arbitrario en el pod. El flag de transacciónREAD ONLYno lo frena: bloquea escrituras al estado de la base, no la creación de procesos externos.
Lo importante para dimensionar el riesgo: un CVSS 9.4 no se saca con un bug teórico. El investigador Mehmet Ince (@mdisec) fue acreditado por la divulgación responsable y aportó un análisis de ambas rutas de explotación con una prueba de concepto funcional, según la nota de release del proyecto.
¿Qué necesita un atacante para explotarlo?
No hace falta ser administrador del cluster, pero tampoco alcanza con estar afuera: el atacante necesita una cuenta de base de datos con propiedad de un esquema o de una base. Desde esa posición puede "sombrear" (shadowing) una función común que el exportador invoca sin calificar, y así colar su código en la próxima corrida de métricas. Es un escenario típico de entornos multi-tenant, donde varios usuarios comparten una misma instancia gestionada.
Se describen dos caminos:
- Métricas personalizadas. Un usuario dueño de un esquema define o altera una función que el exportador ejecuta dentro de una custom query, y ejecuta código en un solo intervalo de scraping.
- Configuración por defecto. La métrica
pg_extensionshacía una llamada a función sin calificar con el esquema, explotable por cualquier usuario no superusuario con propiedad de base de datos —o sea, no requiere que hayas tocado la config de monitoreo.
La superficie más peligrosa aparece cuando se raspan todas las bases con target_databases: '*': multiplica los usuarios que pueden intervenir en una sesión de métricas.
¿Qué versiones están afectadas y a cuáles hay que ir?
Están afectadas todas las versiones previas a 1.28.3 y la 1.29.0. Las versiones corregidas son 1.29.1 y 1.28.3, publicadas como mantenimiento de las dos series soportadas. Si estás en una serie más vieja y sin soporte, la ruta correcta es subir primero a una serie soportada y de ahí al parche.
El release no es solo el fix de seguridad. Según el anuncio oficial en postgresql.org, también trae:
- Remediación de CVEs en dependencias y en el runtime de Go, además del CVE principal.
- Tres bugs del camino de failover HA. Incluyen un problema de retención de labels que podía enrutar escrituras a un ex-primario durante una partición de red (#10409), una condición que impedía disparar el failover cuando un nodo quedaba inalcanzable (#10448) y una guarda contra failovers espurios por fallas transitorias del endpoint HTTP (#10445).
¿En qué consiste el parche del metrics exporter?
La corrección elimina de raíz el superusuario latente: el exportador deja de conectarse como postgres. Ahora usa un rol dedicado, cnpg_metrics_exporter, con únicamente el privilegio pg_monitor y sin permisos de superusuario. Ese rol se mapea vía pg_ident.conf con autenticación peer sobre el socket Unix local —"el mismo patrón usado para cnpg_pooler_pgbouncer", según la documentación del release—. Como session_user nunca es superusuario, RESET ROLE ya no tiene efecto de escalada.
Complementariamente, todas las consultas de monitoreo que vienen de fábrica recibieron calificación explícita con pg_catalog., para que no se las pueda "sombrear" redefiniendo funciones en un esquema del atacante.
¿Qué hago hoy si todavía no puedo actualizar?
Actualizá: es la única solución completa. Si tenés una ventana de mantenimiento pendiente, mitigá mientras tanto con estas medidas, que reducen la superficie pero no reemplazan al parche:
- Calificá tus custom queries. Agregá el prefijo
pg_catalog.a todas las funciones que uses en métricas personalizadas, para cerrar el shadowing. - Restringí la propiedad de bases y esquemas. Limitá qué roles pueden ser owner de una base o un esquema; sin esa propiedad, el vector principal no arranca.
- Evitá el scrapeo con comodín. No uses
target_databases: '*'; apuntá a las bases que realmente necesitás monitorear.
Para la actualización en sí, la recomendación del proyecto es subir primero los clusters primarios de origen y después las réplicas, siguiendo la guía de upgrade específica de tu serie.
¿Por qué esto le importa a cualquiera que corra PostgreSQL en Kubernetes?
Porque rompe una suposición cómoda: que un componente "de solo lectura" es inofensivo. El metrics exporter existe para observar, no para operar, y aun así fue la puerta a un RCE con el usuario postgres dentro del pod. Es el mismo patrón que vimos en otros incidentes recientes del ecosistema cloud-native —un servicio auxiliar, con más privilegios de los que necesita, convertido en pivote—.
La lección práctica va más allá de CloudNativePG: revisá con qué identidad se conectan tus sidecars y exportadores, aplicá mínimo privilegio de verdad (roles dedicados, no SET ROLE sobre una sesión de superusuario) y no confíes en que READ ONLY te salva de la ejecución de comandos. Si además querés endurecer la capa de contenedores y el cluster, tenemos notas complementarias en el blog como "Argo CD sin parche: RCE en repo-server toma tu cluster K8s" y "Tu Docker Asegurado: usuario no root, sistema de archivos de solo lectura y límites de recursos".
Preguntas frecuentes
¿Qué es CVE-2026-44477?
Es una vulnerabilidad crítica (CVSS 9.4) en el metrics exporter de CloudNativePG que permite a un usuario de base de datos con propiedad de esquema o base escalar a superusuario de PostgreSQL y ejecutar comandos en el sistema operativo del pod primario. Es el primer CVE asignado oficialmente al proyecto.
¿A qué versión de CloudNativePG tengo que actualizar?
A 1.29.1 si estás en la serie 1.29, o a 1.28.3 si estás en la 1.28. Están afectadas todas las versiones anteriores a 1.28.3 y la 1.29.0.
¿Necesito una cuenta de base de datos para explotarlo?
Sí. El atacante necesita una cuenta con propiedad de un esquema o de una base dentro de la instancia. No es explotable de forma anónima desde afuera, pero sí por cualquier tenant interno en despliegues compartidos.
¿La transacción READ ONLY no debería bloquear la ejecución?
No. El flag READ ONLY impide escrituras al estado de la base de datos, pero no bloquea la creación de procesos externos con COPY ... TO PROGRAM, que es exactamente lo que usa esta cadena.
¿Qué hago si no puedo actualizar de inmediato?
Mitigá calificando tus custom queries con pg_catalog., restringiendo qué roles pueden ser dueños de bases y esquemas, y evitando target_databases: '*'. Son paliativos: la solución definitiva es el parche.