Noções Básicas de Segurança
A segurança de produção do PostgreSQL começa com um modelo de ameaças: quem pode acessar a rede, como as credenciais são emitidas, se a injeção de SQL é possível e o que os usuários internos podem ler ou alterar. O PostgreSQL 18.4 oferece primitivas fortes (SCRAM, SSL, RLS, roles), mas os padrões são ajustados para desenvolvimento local, não para nuvem exposta à internet.
Receita
-- Role de aplicativo com privilégio mínimo (execute como administrador uma vez)
CREATE ROLE app_api LOGIN PASSWORD 'rotate-me' NOSUPERUSER NOCREATEDB NOCREATEROLE;
GRANT CONNECT ON DATABASE orders TO app_api;
GRANT USAGE ON SCHEMA public TO app_api;
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO app_api;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE ON TABLES TO app_api;# Trecho do pg_hba.conf: TLS + SCRAM apenas para sub-redes de aplicativos
hostssl orders app_api 10.20.0.0/16 scram-sha-256Quando usar isso:
- Integração de novo serviço antes do primeiro deploy em produção
- Revisão pós-incidente quando as credenciais ou os limites de rede não estavam claros
- Preparação para conformidade (SOC2, HIPAA) que exige controles de acesso documentados
Exemplo de Trabalho
Proteja uma API SaaS de banco de dados único: separe roles, revogue padrões públicos, force TLS.
-- 1. Revogar padrões perigosos em um novo banco de dados
REVOKE ALL ON DATABASE orders FROM PUBLIC;
REVOKE ALL ON SCHEMA public FROM PUBLIC;
-- 2. Role de aplicativo: apenas DML
CREATE ROLE app_api LOGIN PASSWORD 'use-vault-generated-secret'
NOSUPERUSER NOCREATEDB NOCREATEROLE;
GRANT CONNECT ON DATABASE orders TO app_api;
GRANT USAGE ON SCHEMA public TO app_api;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_api;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_api;
-- 3. Role de migração: DDL apenas em CI (não em tempo de execução do aplicativo)
CREATE ROLE migrator LOGIN PASSWORD 'ci-only-secret' NOSUPERUSER;
GRANT CONNECT ON DATABASE orders TO migrator;
GRANT CREATE ON SCHEMA public TO migrator;
GRANT ALL ON ALL TABLES IN SCHEMA public TO migrator;
-- 4. Analista somente leitura (BI)
CREATE ROLE analyst_ro LOGIN PASSWORD 'bi-secret' NOSUPERUSER;
GRANT CONNECT ON DATABASE orders TO analyst_ro;
GRANT USAGE ON SCHEMA public TO analyst_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO analyst_ro;# postgresql.conf (gerenciado ou auto-hospedado)
ssl = on
password_encryption = scram-sha-256
log_connections = on
log_disconnections = onO que isso demonstra:
PUBLICnão é confiável por padrão- O aplicativo em tempo de execução usa
app_apiapenas para DML, não superusuário - DDL isolado para
migratorusado em pipelines de implantação - TLS e SCRAM são básicos, não extras opcionais
Mergulho Profundo
Modelo de Ameaças em Resumo
| Ameaça | Vetor | Controle primário |
|---|---|---|
| Exposição de rede | Porta 5432 aberta para a internet | Sub-rede privada, grupos de segurança, apenas hostssl |
| Roubo de credenciais | .env vazado, senha compartilhada | Segredos SCRAM por serviço, rotação, cofre |
| Injeção de SQL | Consultas não parametrizadas | Declarações preparadas, vinculação de parâmetros ORM |
| Acesso interno / privilégio excessivo | GRANT ALL, superusuário compartilhado | Separação de roles, RLS para dados de inquilino |
| Dados em repouso | Snapshot de disco roubado | Criptografia de volume / KMS na nuvem |
Como Funciona
- Autenticação (
pg_hba.conf+pg_authid): o cliente prova a identidade; SCRAM armazena um verificador com salt, não a senha em texto plano. - Autorização (
GRANT/REVOKE, RLS): após o login, cada instrução é verificada em relação aos privilégios de objeto e políticas. - Transporte (SSL/TLS): criptografa bytes em trânsito;
verify-fulltambém valida o nome do host do certificado do servidor. - Auditoria (logging, pgaudit): registra quem se conectou e quais objetos foram acessados para investigações.
Notas do PostgreSQL
-- Confirma a role efetiva e search_path no início da sessão
SELECT current_user, session_user, current_setting('search_path');
-- Lista concessões perigosas
SELECT grantee, privilege_type, table_schema, table_name
FROM information_schema.role_table_grants
WHERE grantee IN ('PUBLIC', 'app_api')
ORDER BY 1, 2;Armadilhas
- Usar o superusuário
postgresna configuração do aplicativo - um comprometimento possui todo o cluster. Correção: roleapp_apidedicada com concessões mínimas. - Deixar concessões
PUBLICem novos bancos de dados - qualquer login pode ler/escrever até que sejam revogadas. Correção:REVOKE ALL ON DATABASE ... FROM PUBLICno runbook de provisionamento. trustoumd5empg_hba.conf- sem criptografia ou senha fraca em trânsito. Correção:hostssl+scram-sha-256para todas as roles não locais.- SQL construído via concatenação de strings - injeção clássica mesmo com ferramentas "internas". Correção: placeholders
$1em todos os drivers; nunca interpole a entrada do usuário. - Mesma senha entre staging e produção - uma violação em staging se torna uma violação em produção. Correção: roles e segredos separados por ambiente; bloquear credenciais de produção em CI não produtivo.
search_pathexcessivamente amplo - sequestro de objetos via schema malicioso. Correção: definirsearch_pathpor role:ALTER ROLE app_api SET search_path = app, public;
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Autenticação IAM/banco de dados (RDS IAM, Cloud SQL IAM) | Sem senhas de banco de dados de longa duração em aplicativos | Driver e caminho de rede suportam tokens IAM |
Autenticação de certificado de cliente (cert em pg_hba) | mTLS entre serviços conhecidos | Muitos clientes de curta duração (dor de rotação) |
| Segurança em nível de linha (RLS) | Schema compartilhado multi-inquilino | Inquilino único com divisão simples de roles é suficiente |
| Apenas política de rede (sem roles de banco de dados) | Sandboxes de desenvolvimento temporários | Qualquer dado de produção com requisitos de conformidade |
FAQs
O PostgreSQL é seguro por padrão?
Não. Os padrões favorecem o desenvolvimento local. A produção requer pg_hba.conf, SCRAM, TLS, concessões de roles e logging explícitos.
Quem deve ter superusuário?
Administradores de "break-glass" e automação que gerencia apenas extensões. Runtimes de aplicativos nunca devem usar superusuário.
Como detectar tentativas de injeção de SQL?
Registre log_statement = 'ddl' para alterações de schema, habilite o logging de conexões e alerte sobre taxas de erro incomuns da role do aplicativo.
O RLS substitui a autorização do aplicativo?
Não. RLS é defesa em profundidade quando o aplicativo se conecta com uma role de banco de dados compartilhada. Verificações na camada do aplicativo ainda são importantes para a experiência do usuário e regras de negócios.
E as extensões e a segurança?
Instale extensões apenas de uma lista de permissões. CREATE EXTENSION requer privilégios elevados; controle via role migrator.
Com que frequência rotacionar senhas?
90 dias para programas de conformidade, ou imediatamente no desligamento de engenheiros e vazamento suspeito. Prefira autenticação IAM/token onde disponível.
Analistas devem ter acesso de gravação?
Raramente. O padrão usual é analyst_ro somente leitura com mascaramento de colunas ou visualizações excluindo PII.
Como proteger o Postgres gerenciado?
Você ainda é responsável pelas regras de rede, IAM, extensões e design de consultas. Veja Noções Básicas de PostgreSQL Gerenciado.
Quais logs são o mínimo para segurança?
log_connections, log_disconnections, falhas de autenticação (via erros de conexão) e alterações de DDL. Expanda com pgaudit para conformidade.
Posso bloquear `COPY TO PROGRAM`?
Sim. Não conceda superusuário; revogue pg_execute_server_program de roles de aplicativo no PostgreSQL 15+.
Relacionado
- Configuração de SSL/TLS - criptografar conexões
- Autenticação SCRAM - hashing de senha
- pgaudit e Logging de Conformidade - trilhas de auditoria
- Criptografia em Repouso - proteção de disco e snapshot
- Melhores Práticas de Segurança - checklist operacional
Versões da Pilha: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x e PostGIS 3.5+.