Si corrés PostgreSQL sobre Kubernetes con el operador CloudNativePG, hay una novedad que exige mirar la versión que tenés desplegada antes de seguir leyendo. La CVE-2026-44477, con un puntaje CVSS 9.4 (crítico), convierte al componente más inocente del stack —el exporter de métricas de Prometheus— en un camino directo desde un rol de base sin privilegios hasta el superusuario de PostgreSQL y, de ahí, a ejecución de comandos en el sistema operativo del pod primario. Fue reportada por el investigador Mehmet Ince y parcheada en las versiones 1.29.1 y 1.28.3 el 8 de mayo de 2026.
CVE-2026-44477 es una vulnerabilidad de escalada de privilegios en el metrics exporter de CloudNativePG, el operador open source de Kubernetes que gestiona clusters de PostgreSQL. El exporter se conectaba a la base como superusuario postgres y bajaba de rol con SET ROLE pg_monitor, pero esa democión era reversible. Un rol de aplicación común podía recuperar el superusuario y ejecutar comandos en el sistema operativo. Afecta versiones anteriores a 1.28.3 y desde 1.29.0 hasta 1.29.1.
¿Por qué un exporter de métricas termina dando RCE?

Porque el exporter se autenticaba con más privilegios de los que necesitaba. Para leer métricas alcanza con el rol pg_monitor, pero el proceso abría la conexión como el superusuario postgres a través del socket Unix local del pod y recién después degradaba la sesión. Ese diseño dejaba una identidad de superusuario "dormida" dentro de cada scrape, y todo el resto de la cadena consiste en despertarla.
El detalle técnico que rompe el modelo es cómo funciona SET ROLE en PostgreSQL. La instrucción cambia current_user, pero no toca session_user: la sesión sigue siendo, por debajo, la del superusuario. Cualquier expresión SQL evaluada dentro de la sesión de scrape puede llamar a RESET ROLE y volver a ser postgres. Podés reproducir el mecanismo en cualquier consola para entenderlo:
SET ROLE pg_monitor;
SELECT session_user, current_user; -- session_user = postgres, current_user = pg_monitor
RESET ROLE; -- de nuevo superusuario
SELECT session_user, current_user; -- ambos = postgres¿Cómo es la cadena de escalada de privilegios completa?
La cadena va de un rol de aplicación sin privilegios a superusuario de PostgreSQL y luego a ejecución de comandos en el pod, todo dentro de un mismo intervalo de scrape. El punto de entrada es que un atacante logra que su propio SQL se ejecute dentro de la sesión privilegiada del exporter, y desde ahí desarma la democión de rol.
- Inyección de un identificador sombra. Un usuario que posee un schema en el
search_pathde una base escrapeada planta un objeto (una función, por ejemplo) cuyo nombre coincide con un identificador sin calificar usado en una query de métricas. Cuando el exporter corre esa query, ejecuta el objeto del atacante. - Recuperación del superusuario. Dentro de esa ejecución, un
RESET ROLEdevuelve la identidad real de la sesión —postgres— porquesession_usernunca dejó de serlo. - Salto al sistema operativo. Con el superusuario recuperado,
COPY ... TO PROGRAMlanza un subproceso a nivel de OS como el usuariopostgresdentro del pod primario. El flag de transacciónREAD ONLYno lo frena: bloquea escrituras a la base, no procesos externos.
Lo más incómodo es que había dos caminos, y el segundo no requería configuración custom. Según el advisory oficial de CloudNativePG (GHSA-423p-g724-fr39), el archivo default-monitoring.yaml que viene de fábrica contenía una llamada a current_database() sin calificar. Eso significaba que en un deploy stock, cualquier usuario dueño de una base —incluido el rol app por defecto— podía disparar la escalada sin tocar nada. La cadena entrega, en palabras del propio advisory, "superuser privilege escalation plus arbitrary OS command execution inside the primary pod from a low-privileged database role".
¿Qué versiones están afectadas y cuáles traen el parche?
Están afectadas todas las versiones anteriores a 1.28.3 y la rama 1.29 anterior a 1.29.1; el arreglo está en 1.28.3 y 1.29.1. El vector CVSS 4.0 publicado es CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H, que refleja bajo privilegio requerido, sin interacción del usuario e impacto total sobre confidencialidad, integridad y disponibilidad.
- Vulnerables: todas las versiones
< 1.28.3y el rango>= 1.29.0, < 1.29.1. - Parcheadas:
1.28.3y1.29.1, publicadas el 8 de mayo de 2026 según el anuncio oficial del proyecto. - Verificá la actual: el proyecto libera parches con frecuencia; antes de actualizar confirmá cuál es la última versión estable en la página de releases oficial en lugar de fijar un número de memoria.
¿Cómo funciona el parche que aplicó CloudNativePG?
El parche elimina la raíz del problema: el exporter dejó de autenticarse como superusuario. En su lugar usa un rol dedicado cnpg_metrics_exporter con solo los privilegios de pg_monitor, mapeado por peer authentication vía pg_ident.conf. Sin una identidad de superusuario en la sesión, RESET ROLE ya no tiene a qué volver.
Además, el equipo endureció, según el anuncio de la versión 1.29.1, todas las queries de monitoreo incluidas con calificación explícita pg_catalog. —de modo que un objeto sombra en el search_path del atacante ya no puede secuestrar un identificador como current_database(). Es la aplicación práctica de un principio viejo de PostgreSQL: nunca dejes identificadores sin calificar en SQL que corre con privilegios.
¿Qué implica esto para un cluster en producción?
Implica que un tenant o una aplicación con acceso de escritura básico a "su" base podía comprometer el pod primario completo, no solo su propio esquema. En entornos multi-tenant sobre Kubernetes, donde varios equipos comparten un mismo operador, ese es exactamente el límite de aislamiento que se supone que un operador debe sostener.
La superficie real depende de tu topología. Si usás target_databases: '*' para escrapear todas las bases del cluster, cada base con un dueño no confiable es un punto de entrada. Si el monitoreo por defecto está activo —lo habitual—, estabas expuesto por el segundo camino incluso sin queries de métricas custom. Y como el ataque se ejecuta dentro del intervalo de scrape, no deja el rastro típico de un login sospechoso: es tráfico de monitoreo legítimo.
¿Qué podés hacer hoy para protegerte?
Lo primero y no negociable es actualizar el operador a 1.28.3, 1.29.1 o superior. Si no podés parchear de inmediato, hay mitigaciones que reducen la exposición, pero ninguna reemplaza al upgrade.
- Actualizá el operador. Subí CloudNativePG a una versión parcheada de tu rama (1.28.3 o 1.29.1 como piso). El fix vive en el operador y en las queries de monitoreo que despliega.
- Calificá tus queries custom. Si tenés métricas propias, prefijá todo identificador de catálogo con
pg_catalog.(por ejemplopg_catalog.current_database()) para que ningún objeto en elsearch_pathpueda suplantarlo. - Limitá el alcance del scrape. Evitá
target_databases: '*'cuando puedas y apuntá a bases conocidas y controladas. - Controlá quién posee bases y schemas. Asegurate de que solo roles de confianza sean dueños de bases y schemas en clusters escrapeados; el atacante necesita esa propiedad para plantar el objeto sombra.
Revisá qué versión corrés. Podés inspeccionar la imagen del deployment del operador para confirmar la versión desplegada antes y después del cambio:
kubectl get deployment -n cnpg-system \
-o jsonpath='{.items[*].spec.template.spec.containers[*].image}'Ajustá el namespace si instalaste el operador en otro lugar.
Preguntas frecuentes
¿CVE-2026-44477 fue explotada en la práctica?
Las fuentes públicas la describen como una vulnerabilidad reportada de forma responsable por el investigador Mehmet Ince y corregida antes de la divulgación, sin campañas de explotación confirmadas en el momento del anuncio. Aun así, con un exploit documentado y CVSS 9.4, tratala como si fuera a ser explotada: parcheá.
¿Estoy afectado si no uso el metrics exporter?
El riesgo vive en el exporter de métricas del operador, activo por defecto en instalaciones estándar. Si tu deploy tiene el monitoreo por defecto habilitado —lo más común—, estabas expuesto por el camino que no requiere queries custom. La forma segura de descartarlo es actualizar el operador, no asumir que el exporter está apagado.
¿Alcanza con desactivar las métricas en lugar de actualizar?
No es la solución recomendada. Apagar el monitoreo reduce la superficie, pero te deja sin observabilidad y no corrige la raíz —una sesión que se autentica como superusuario. La corrección real es el rol cnpg_metrics_exporter con privilegios acotados que introduce el parche.
¿Por qué SET ROLE no bastaba para bajar de privilegios?
SET ROLE cambia solo current_user; session_user —la identidad con la que se autenticó la conexión— permanece intacta. Por eso un RESET ROLE devuelve el superusuario original. Para dejar de ser superusuario de verdad hay que conectarse desde el principio con un rol sin ese privilegio, que es justamente lo que hace el parche.
¿Qué relación tiene con otras vulnerabilidades de Postgres o Kubernetes?
Es parte de una racha de fallos donde componentes de infraestructura confiables abren caminos de escalada; en este blog cubrimos casos vecinos como el SQLi sin auth de Metabase (CVE-2026-72898) y el path de Ingress que da RCE en Kubernetes (CVE-2026-24512). El patrón se repite: privilegios excesivos por defecto en piezas que parecen periféricas. Si te interesa el motor por debajo, nuestra nota sobre PostgreSQL 18 es una buena lectura complementaria.
El cierre práctico: abrí tu cluster, mirá la versión del operador y, si está por debajo de 1.28.3 o 1.29.1, planificá el upgrade hoy. Un exporter de métricas no debería poder darle a nadie una shell en tu primario, y ahora tenés el parche que se asegura de eso.