Seguridad general de PostgreSQL | Nicolás Garzón
La seguridad de PostgreSQL no depende de una sola opción. Es una cadena: red, autenticación, roles, SQL, datos, operación, backups y respuesta a incidentes. Una capa débil puede invalidar las demás.
Antes de configurar, identifica:
Actores legítimos y privilegios.
Datos sensibles.
Orígenes de conexión.
Servicios y terceros.
Riesgo de aplicación comprometida.
Administradores y acceso de emergencia.
Requisitos de retención y recuperación.
Impacto de lectura, modificación o indisponibilidad.
Seguridad sin threat model suele convertirse en una checklist incompleta.
Texto
Copiar red
→ TLS/autenticación
→ role y ownership
→ permisos/RLS
→ SQL parametrizado
→ constraints
→ cifrado/minimización
→ auditoría
→ backups/DRNinguna capa debe asumir que la anterior es infalible.
No expongas el puerto a Internet sin necesidad.
Usa redes privadas, firewall y allowlists mínimas.
Separa tráfico de aplicación, administración y replicación.
Monitorea intentos fallidos.
Una red privada reduce superficie, pero no reemplaza TLS ni credenciales.
Usa verificación completa del servidor. Gestiona:
CA.
Hostname.
Rotación y expiración.
Certificados cliente cuando aplique.
Protocolos/ciphers soportados.
No uses sslmode=require como sinónimo de identidad verificada.
SCRAM o mecanismo administrado fuerte.
Cuenta por servicio/entorno.
Secret manager.
Rotación.
Tokens temporales cuando estén disponibles.
Nada de passwords en repositorio, logs o imágenes.
Revocar una credencial puede requerir terminar sesiones existentes.
Owner NOLOGIN.
Migration role controlado.
Runtime mínimo.
Reporting/backup/monitoring separados.
Nada de superuser/BYPASSRLS para la app.
Default privileges versionados.
Revocar privilegios innecesarios de PUBLIC.
Prueba acceso efectivo con cada role real.
Un schema escribible por un atacante puede introducir objetos con nombres esperados por funciones privilegiadas.
SQL
Copiar SET search_path = pg_catalog, trusted_schemay califica nombres. No incluyas schemas escribibles por callers antes de los confiables.
Parámetros para valores.
Whitelist para identifiers/operadores.
APIs raw auditadas.
Inputs de pequeños lenguajes limitados.
Timeouts contra consultas abusivas.
Runtime sin DDL para limitar impacto.
RLS añade defensa por fila. Mantén también:
tenant_id tipado.
Unique/FK compuestas.
Contexto con SET LOCAL.
Runtime no owner.
Tests de conexión reutilizada.
Para requisitos fuertes puede preferirse database/cluster separado; RLS no es aislamiento físico.
La seguridad también incluye integridad:
No aceptar references cross-tenant.
No permitir estados imposibles.
Proteger unicidad concurrente.
Limitar tamaños/rangos.
Un atacante o bug con permisos de escritura sigue sujeto a constraints.
PII.
Credenciales/tokens.
Información financiera/salud.
Datos de auditoría.
Aplica minimización: no guardes lo que no necesitas. Define retención y borrado en tablas, JSONB, logs, réplicas y backups.
Disk/storage encryption del sistema/proveedor protege medios, no a un role SQL autorizado.
Útil para datos que ni administradores de DB deberían ver fácilmente, pero complica búsqueda, rotación, índices y recuperación.
No almacenes claves junto a los datos cifrados sin separación útil.
La aplicación debe usar un algoritmo de password hashing diseñado para ello y almacenar solo el hash. No uses cifrado reversible ni hashes rápidos SQL como MD5/SHA sin KDF adecuada.
PostgreSQL no debería recibir el password en logs o auditoría.
Revisa SECURITY DEFINER.
Revoca EXECUTE público cuando corresponda.
Controla dynamic SQL.
Instala extensiones confiables y mantenidas.
Actualiza por CVEs.
No permitas lenguajes no confiables sin justificación.
Protege contra agotamiento:
Pool limitado/backpressure.
Statement/lock timeouts.
Límites de tamaño y paginación.
Regex/JSONPath/FTS controlados.
Quotas y rate limiting en aplicación.
Disk/WAL/slots monitoreados.
Un usuario autorizado puede causar DoS con una consulta válida y costosa.
Registra actor, acción y resultado sin secretos. Separa permisos del audit log y expórtalo cuando se necesite inmutabilidad.
Auth failures.
Cambios de roles/grants.
DDL.
Accesos privilegiados.
Exportaciones masivas.
Desactivación de RLS/triggers/logging.
Cifrados.
Acceso separado.
Inmutables/off-account cuando corresponda.
Retención definida.
Restore probado.
Borrado seguro.
Un backup olvidado puede ser la copia más vulnerable del sistema.
Mantén minor releases soportadas, OS, drivers y extensiones. Antes de actualizar:
Revisa advisories/release notes.
Prueba.
Confirma backup/rollback.
Verifica replicas/extensions.
No permanezcas en una major sin soporte.
Bastion/VPN.
MFA en proveedor.
Accesso just-in-time.
Sesiones nominativas, no cuenta compartida.
Break-glass auditado y rotado.
Separación de funciones.
IaC y revisión de cambios.
Contener acceso.
Preservar evidencia.
Rotar secretos/certificados.
Identificar alcance y queries.
Revisar backups/exfiltración.
Recuperar en entorno limpio.
Notificar según obligaciones.
Corregir causa y monitorear.
No borres logs ni reinicies indiscriminadamente antes de conservar evidencia.
Role revocado conserva sesión activa.
Owner bypassa RLS.
Restore recrea grants inseguros.
Extension no parcheada.
Log contiene tokens.
Replica/reporting role exfiltra datos.
SQL parametrizado ejecuta regex costosa.
Backup cifrado pero key comprometida en misma cuenta.
Confiar solo en firewall.
Runtime owner/superuser.
TLS sin verificación.
Secrets compartidos.
RLS sin constraints.
Cifrar todo sin estrategia de claves.
Logs con PII.
Backups sin restore.
Parches postergados indefinidamente.
Checklist sin threat model.
Inventario de datos y roles.
Red/TLS/HBA.
Secrets/rotación.
Ownership/grants/defaults.
RLS/constraints.
Injection/timeouts.
Functions/extensions.
Logs/auditoría.
Backups/DR.
Patching/incidentes.
¿Qué protege encryption at rest y qué no?
¿Por qué constraints son parte de seguridad?
¿Qué riesgo tiene un schema escribible en search path?
¿Por qué una query parametrizada aún puede causar DoS?
¿Qué debes hacer con sesiones tras rotar/revocar?
Ver respuestas
Protege medios/archivos, no impide que un role autorizado lea datos.
Limitan estados y referencias incluso si un writer está comprometido.
Puede secuestrar resolución de nombres en código privilegiado.
Puede contener una operación válida pero extremadamente costosa.
Evaluar y terminar sesiones existentes para aplicar la revocación efectiva.
PostgreSQL en producción reúne disponibilidad, despliegues, capacidad y operación cotidiana.