Seguridad pgAdmin: lo que ZoomEye no te dice
En pocas palabras: El 31/10/2026, ZoomEye mostró 0 resultados para app=”pgAdmin” y 47.757 para title=”pgAdmin”, pero eso no mide exposición real: la seguridad depende del modo servidor (default desde la versión 2), la confianza en el proxy inverso y controles de login como ALLOWED_HOSTS y MAX_LOGIN_ATTEMPTS.
El 31 de octubre de 2026, una consulta en ZoomEye con app="pgAdmin" devolvió 0 resultados, mientras que title="pgAdmin" devolvió 47.757 páginas, según el análisis publicado por Ioneyrezende en dev.to. A simple vista parece una contradicción —¿cómo hay cero apps pero casi 48 mil títulos?— pero no lo es. Son dos preguntas distintas hechas a la misma base de datos, y la respuesta a cuál importa más depende de qué estás tratando de proteger.
pgAdmin es la herramienta de administración de PostgreSQL que corre en modo desktop o en modo servidor, el esquema por defecto desde la versión 2 según la documentación oficial de despliegue. En modo servidor los usuarios inician sesión, existe un superusuario inicial y el almacenamiento queda aislado por usuario bajo STORAGE_DIR. Esa diferencia define si una página pública es una superficie de autenticación real o un desktop expuesto por error.
En este artículo:
- En resumen
- ¿Qué encontró la observación de ZoomEye sobre pgAdmin?
- ¿Por qué el modo servidor de pgAdmin cambia el riesgo de seguridad?
- ¿Cómo evaluar si una identidad de proxy es confiable en pgAdmin?
- ¿Qué configuraciones evitan ataques de Host Header Injection en pgAdmin?
- ¿Qué controles de login refuerzan la seguridad pgAdmin frente a fuerza bruta?
- ¿Por dónde conviene empezar si administrás un pgAdmin expuesto?
- ¿Cómo probar si un despliegue de pgAdmin está realmente protegido?
- Qué está confirmado y qué queda pendiente de verificación
- Errores comunes al evaluar la seguridad de pgAdmin expuesto
- Preguntas Frecuentes
- Conclusión
- Fuentes
En resumen
- ZoomEye registró 0 resultados para
app="pgAdmin"y 47.757 paratitle="pgAdmin"el 31/10/2026, con page 1, page size 1 y sub_type=all. - El modo servidor de pgAdmin es el default desde la versión 2 y exige login con un superusuario inicial.
- Un header de proxy no sobrescrito (X-Script-Name, X-Scheme) puede dejar que un atacante altere identidad o URLs generadas.
- ALLOWED_HOSTS vacío deja la aplicación abierta a Host Header Injection, según la documentación de configuración oficial.
- MAX_LOGIN_ATTEMPTS tiene un default de 3 intentos, pero solo protege cuentas INTERNAL, no LDAP, OAUTH2, KERBEROS ni WEBSERVER.
¿Qué encontró la observación de ZoomEye sobre pgAdmin?
La consulta encontró un número alto de páginas con el título “pgAdmin” (47.757) frente a cero coincidencias de la categoría de aplicación (app="pgAdmin"), ambas tomadas el mismo día con los mismos parámetros de paginación. El cero no es un error de la búsqueda: es un resultado válido para ese filtro puntual. El número alto, en cambio, funciona como pista de descubrimiento, no como conteo de servidores desprotegidos.
Vale la aclaración, porque no es un detalle menor: app= y title= no están midiendo lo mismo. Nuestra lectura —razonable a partir de cómo suelen operar este tipo de motores de escaneo, aunque no confirmada punto por punto por ZoomEye— es que app= funciona como una huella digital activa: necesita que la herramienta reconozca específicamente que ese software está corriendo. title=, en cambio, es una búsqueda de texto sobre cualquier etiqueta HTML <title> que contenga la palabra “pgAdmin”, sin importar si se trata de una instancia real, una captura de pantalla en un blog o una página de documentación. Por eso la brecha entre 0 y 47.757 no es una paradoja: son dos preguntas distintas respondidas con precisión distinta.
Un título pgAdmin puede aparecer en una página de login, en documentación, o en cualquier página que simplemente mencione la palabra. La observación no muestra si el despliegue corre en modo servidor, si el login funciona, ni qué servidores de base de datos tiene registrados esa instancia. Eso requiere verificación del propietario. Complementá con comparativa de seguridad y privacidad con GitHub.
Dicho de otra forma: es un dato crudo, nada más. Lo interesante empieza después, cuando alguien tiene que decidir qué hacer con una lista de 47.757 títulos sospechosos.
¿Por qué el modo servidor de pgAdmin cambia el riesgo de seguridad?

El modo servidor cambia el riesgo porque suma una capa de autenticación web que el modo desktop no tiene. Desde la versión 2, server mode es la configuración por defecto de pgAdmin, según la misma documentación de despliegue. Al activarse, se crea un superusuario inicial y cada cuenta autenticada tiene su propio directorio de almacenamiento bajo STORAGE_DIR, sin acceso al filesystem completo del servidor.
En modo desktop no hay nada de esto: cada usuario corre una instancia local, sin login web, sin superusuario compartido. Por eso revisar el modo de despliegue antes de aplicar cualquier control es el primer paso al hacer inventario de instancias pgAdmin encontradas en un escaneo, sea con ZoomEye o con cualquier otra herramienta. Te puede servir nuestra cobertura de checks de seguridad en pipelines de AWS.
¿Cómo evaluar si una identidad de proxy es confiable en pgAdmin?
La identidad de proxy es confiable solo si el reverse proxy sobrescribe los headers que pgAdmin usa para identificar al cliente, nunca si los deja pasar tal como llegan. pgAdmin acepta X-Script-Name y X-Scheme de forma incondicional, mientras que los headers X-Forwarded-* se confían solo hasta la profundidad fijada en PROXY_X_*_COUNT, según la documentación de despliegue en servidor. Si un atacante controla alguno de esos headers sin que el proxy los reemplace, puede alterar las URLs que genera la aplicación o directamente suplantar identidad.
Ojo con esto: la configuración estática del proxy no basta. Hay que revisar la cadena completa desde el navegador hasta pgAdmin, no solo el archivo de configuración de NGINX, Apache o Caddy.
Ejemplo hipotético (no corresponde a ningún caso verificado): imaginemos un equipo chico que levanta pgAdmin en un VPS propio, lo pone en modo servidor detrás de NGINX y copia una configuración genérica de internet sin agregar las líneas proxy_set_header X-Script-Name ""; ni proxy_set_header X-Scheme "";. Si alguien manda una request directa con su propio header X-Script-Name apuntando a un dominio que controla, y ese header llega hasta pgAdmin sin ser sobrescrito, la aplicación podría construir las URLs de reset de contraseña usando ese valor en lugar del dominio real. Un usuario legítimo que pide “olvidé mi contraseña” recibiría un mail con un link armado sobre esa base. No haría falta explotar ninguna falla de PostgreSQL: alcanzaría con la confianza puesta en un header que nadie se encargó de neutralizar. Es un escenario construido para ilustrar por qué la documentación insiste en sobrescribir esos headers, no un hecho reportado.
¿Qué configuraciones evitan ataques de Host Header Injection en pgAdmin?
ALLOWED_HOSTS vacío es la configuración que abre la puerta a Host Header Injection en pgAdmin: según la documentación de archivos de configuración, un valor vacío acepta cualquier IP. La corrección suena simple en el papel: completar ALLOWED_HOSTS con los hostnames conocidos del despliegue y validar contra esa misma lista los redirects y los links de recuperación de contraseña. En la práctica, requiere que alguien se siente a mapear todos los hostnames legítimos antes de cerrar la puerta —si falta uno, se rompe el acceso de un equipo entero.
El reverse proxy, además, debería rechazar el acceso directo al listener de la aplicación. Si alguien puede pegarle directamente al puerto donde corre Gunicorn o uWSGI, el ALLOWED_HOSTS del lado de pgAdmin deja de ser la única barrera. Si vas a levantar pgAdmin en un VPS propio detrás de NGINX, conviene partir de una infraestructura que controlás de punta a punta, como la que ofrece donweb.com para instancias cloud en Argentina.
¿Qué controles de login refuerzan la seguridad pgAdmin frente a fuerza bruta?
Para cuentas con autenticación INTERNAL, pgAdmin bloquea la cuenta tras MAX_LOGIN_ATTEMPTS intentos fallidos consecutivos, con un default de 3, según la documentación de la página de login. Para fuentes externas (LDAP, OAUTH2, KERBEROS, WEBSERVER) esa protección no aplica: pgAdmin no hace rate limiting ahí, hay que configurarlo en el proveedor de identidad o en el proxy, por ejemplo con limit_req en NGINX.
El tema es que el superusuario inicial no debería quedar como cuenta compartida. Conviene revisar cada usuario de pgAdmin, su fuente de autenticación y a qué servidores de base de datos puede conectarse, porque una cuenta que puede abrir una definición de servidor guardada puede llegar a una credencial de base de datos aunque esa cuenta no sea superusuario de PostgreSQL. Activar la autenticación de dos factores cuando la política del despliegue lo exija suma otra capa de control.
¿Por dónde conviene empezar si administrás un pgAdmin expuesto?
No todos los controles pesan lo mismo en todos los escenarios. Antes de salir a corregir todo a la vez, tiene sentido ordenar según cómo está desplegado el pgAdmin que estás mirando. Estos son criterios de priorización que armamos a partir de lo que detalla la documentación oficial, no un checklist universal:
- Si pgAdmin es multiusuario y accesible desde internet: primero ALLOWED_HOSTS y la revisión de headers del proxy (X-Script-Name, X-Scheme). Son los dos puntos que, si fallan, comprometen a cualquier usuario, no solo al admin.
- Si tiene cuentas con fuentes de autenticación mixtas (INTERNAL + LDAP/OAUTH2): confirmar que el rate limiting esté cubierto en ambos lados, porque MAX_LOGIN_ATTEMPTS protege solo a las cuentas INTERNAL y deja un punto ciego en las externas.
- Si es una instancia de un solo administrador, accesible solo por VPN: la urgencia de ALLOWED_HOSTS y proxy headers baja, pero no desaparece —igual conviene resolverlo antes de abrir el acceso a un segundo usuario.
- Si nunca se auditaron los servidores registrados por cada cuenta: esto va último en la lista de urgencia pero no de importancia. Una cuenta con acceso a un servidor de producción que ya nadie recuerda por qué está ahí es, con el tiempo, tan riesgosa como un header mal configurado.
¿Cómo probar si un despliegue de pgAdmin está realmente protegido?
Probar un despliegue implica simular un atacante desde una red no confiable: pedir la página de login y una página protegida, mandar un header de proxy falsificado, un Host no permitido y un intento de login sin credenciales. Cada una de esas pruebas debería fallar de forma segura, sin filtrar información ni dejar pasar la sesión. Cubrimos ese tema en detalle en hardening de seguridad para organizaciones.
Desde una red aprobada, el otro lado de la verificación es loguearse con un usuario de bajo privilegio y confirmar que no puede administrar usuarios ni llegar a servidores fuera de su autorización. Este es un criterio de verificación propuesto para este análisis, no algo que hayamos ejecutado contra un despliegue real, y conviene tomarlo como punto de partida antes de sacar conclusiones sobre cualquier instancia encontrada en un escaneo.
Qué está confirmado y qué queda pendiente de verificación
- Confirmado: server mode es el default de pgAdmin desde la versión 2, según la documentación oficial.
- Confirmado: ALLOWED_HOSTS vacío acepta cualquier IP y habilita Host Header Injection.
- Confirmado: pgAdmin honra X-Script-Name y X-Scheme sin condición, a diferencia de los X-Forwarded-*.
- Confirmado: MAX_LOGIN_ATTEMPTS tiene default de 3 y solo aplica a cuentas INTERNAL.
- Pendiente: cuántas de las 47.757 páginas con título pgAdmin corresponden a instancias reales en modo servidor.
- Pendiente: cuántas de esas instancias tienen login expuesto sin lockout, 2FA o rate limiting activo.
Errores comunes al evaluar la seguridad de pgAdmin expuesto
- Tratar el conteo de títulos como conteo de vulnerables: 47.757 es una pista de descubrimiento, no la cantidad de servidores sin protección.
- Dejar ALLOWED_HOSTS vacío “porque total está detrás de un proxy”: el valor vacío acepta cualquier IP igual, con o sin proxy delante.
- Confiar en que el proxy ya filtra todo por defecto: si no sobrescribe X-Script-Name y X-Scheme, un cliente puede mandarlos directamente.
- Dejar el superusuario inicial como login compartido del equipo: cada acceso debería tener su propia cuenta y su propio alcance de servidores.
Preguntas Frecuentes
¿Qué diferencia hay entre pgAdmin en modo desktop y modo servidor?
En modo desktop cada usuario corre una instancia local sin login web. En modo servidor, el default desde la versión 2, los usuarios se autentican, existe un superusuario inicial y el almacenamiento queda aislado por cuenta bajo STORAGE_DIR. Lo explicamos a fondo en guía de auditoría de seguridad en WordPress.
¿Es peligroso tener pgAdmin expuesto en internet?
Depende de la configuración, no de la mera exposición. Un pgAdmin en modo servidor con ALLOWED_HOSTS configurado, proxy que sobrescribe headers, MAX_LOGIN_ATTEMPTS activo y usuarios revisados puede estar público sin ser un riesgo mayor que cualquier otro panel de administración.
¿Cómo se configura la autenticación detrás de un reverse proxy en pgAdmin?
pgAdmin soporta autenticación webserver detrás de un reverse proxy, pero el proxy debe sobrescribir el header de identidad en cada request, nunca pasarlo tal como lo manda el cliente. La confianza en ese header queda limitada a proxies configurados explícitamente.
¿Qué es ALLOWED_HOSTS en pgAdmin y para qué sirve?
ALLOWED_HOSTS es el parámetro de config.py que valida contra qué hostnames puede responder pgAdmin. Si queda vacío, acepta cualquier IP y queda expuesto a Host Header Injection, según la documentación oficial de configuración.
¿Un título pgAdmin en ZoomEye significa que el servidor está desprotegido?
No. El título solo indica que una página menciona “pgAdmin”, sea login, documentación u otra referencia. Confirmar si está desprotegido exige revisar el modo de despliegue, la configuración del proxy y los controles de login de esa instancia puntual.
Conclusión
El número de ZoomEye (47.757 títulos contra 0 coincidencias de app) deja clara una cosa: un escaneo masivo no reemplaza la verificación caso por caso. Para cualquier equipo que tenga pgAdmin público, el trabajo real es revisar el modo de despliegue, confirmar que el proxy sobrescribe los headers de identidad, llenar ALLOWED_HOSTS, activar MAX_LOGIN_ATTEMPTS o su equivalente en el proveedor externo, y auditar qué servidores de base de datos puede alcanzar cada usuario. Nada de esto se resuelve mirando un conteo de ZoomEye, y tampoco se resuelve todo el mismo día: priorizar según el escenario —multiusuario e internet-facing primero, instancia solitaria detrás de VPN después— es lo que separa un parche apurado de una corrección que se sostiene.






