Dev & EngARTIGO

Pesquisador encontra 76 falhas em extensões que travam o superusuário no Postgres gerenciado

Mehmet Ince mostra como validadores de Foreign Data Wrapper e truques de search_path permitem escapar das camadas de segurança que Azure, AWS, Google, Supabase, Aiven, Neon, PlanetScale e Xata.io usam para impedir que clientes virem superusuário de verdade.

Pesquisador encontra 76 falhas em extensões que travam o superusuário no Postgres gerenciado
Imagem gerada por IA

O pesquisador de segurança Mehmet Ince publicou em 23 de setembro de 2026 a segunda parte de uma série de seis artigos sobre riscos sistêmicos na indústria de Postgres↳PostgreSQL11 conteúdosPostgreSQL via SSL com GolangData · abr 20195 itens legais sobre data types do PostgreSQLData · mar 20195 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data → gerenciado. A primeira parte, de um mês antes, descrevia uma técnica de backdoor de superusuário baseada em shared buffer; nesta segunda, Ince muda o foco para as chamadas "security hardening extensions", as extensões que provedores como Supabase, Aiven, Azure↳Azure76 conteúdosDeploy de Azure Stream Analytics job com CI/CD usando Azure PipelinesDevSecOps · mai 2019Azure – Como criar uma base de dados SQL no Microsoft Azure pronta para ser utilizadaData · abr 2019Azure Static Web Apps com Vue.js e Visual Studio CodeDevSecOps · out 2023Ver tudo em DevSecOps →, AWS Aurora, Google AlloyDB, Neon, PlanetScale e Xata.io usam para impedir que o cliente, mesmo sem ser superusuário de verdade, rode operações que exigiriam esse privilégio.

O material é denso e técnico, publicado no Planet PostgreSQL, e serve de base para uma palestra de 40 minutos de Ince na PGCONF.EU. Ele deixou explícito que não vai conseguir cobrir tudo no palco e por isso está publicando o restante em texto. Para quem constrói sobre Postgres gerenciado, especialmente arquiteturas multi-tenant, o conteúdo importa porque mexe direto na camada que separa "seu banco" do "banco do vizinho".

O que são as extensões de hardening e por que existem

Quando você contrata um Postgres gerenciado, raramente recebe o papel rolsuper de verdade. Ainda assim, consegue rodar operações que normalmente exigiriam superusuário, como criar extensões ou configurar publicações lógicas. Isso não é mágica: é uma extensão de hardening rodando dentro do backend↳Back-end49 conteúdosIntegração front-end com backend: 7 decisões que evitam caos entre APIs, BFF e GraphQLDev (Back & Front) · abr 2026Como criar uma FAKE API REST para testes — JSONPlaceholderDev (Back & Front) · set 2025Construindo um aplicativo de bate-papo de IA simples com Spring AI e AngularDev (Back & Front) · jul 2025Ver tudo em Dev (Back & Front) →, interceptando cada statement antes da execução para decidir se aquele comando pode ser liberado.

O problema, segundo Ince, é que essa decisão não é um simples sim ou não. Para liberar operações legítimas, a extensão precisa trocar temporariamente a identidade do backend para um papel de superusuário do provedor, deixar o núcleo do Postgres processar o comando do cliente sob esse privilégio elevado e, depois, restaurar a identidade original. É exatamente essa janela de privilégio elevado que vira alvo.

Existem hoje implementações equivalentes em praticamente todo provedor relevante: supautils no Supabase, aiven_extras na Aiven, azure.so na Azure, rdsutils.so na família Aurora da AWS, pg_pscale_utils no PlanetScale, xatautils na Xata.io, além de mecanismos internos equivalentes no Google AlloyDB e no Neon. Ince testou as oito implementações ao longo de três meses e reportou, no total, 76 vulnerabilidades distintas ligadas apenas a essas camadas de hardening.

Caso 1: validador malicioso sequestra a janela de superusuário

O primeiro caso documentado explora CREATE FOREIGN DATA WRAPPER, comando que normalmente só um superusuário roda. Como todo provedor precisa liberar Foreign Data Wrappers para o cliente, a extensão de hardening reconhece esse tipo de statement, troca o current_user para o papel de superusuário interno e delega o comando original ao núcleo do Postgres através do hook run_process_utility_hook_with_cleanup.

O ponto cego, segundo Ince, é que a extensão nunca resolve nem valida quais OIDs de função serão efetivamente executados durante essa janela elevada; ela apenas repassa o texto do comando e deixa o núcleo do banco resolver os nomes de novo, já sob privilégio de superusuário. Isso abre a porta para um validador de FDW malicioso, escrito pelo próprio atacante, que roda como superusuário assim que é invocado:

sql
CREATE FUNCTION public.evil_validator(text[], oid)
RETURNS void LANGUAGE plpgsql AS $$
BEGIN
 EXECUTE 'CREATE ROLE callback_super NOLOGIN SUPERUSER';
 EXECUTE format('GRANT callback_super TO %I', session_user);
END $$;

CREATE FOREIGN DATA WRAPPER callback_fdw
 NO HANDLER
 VALIDATOR public.evil_validator
 OPTIONS (invoke 'now');

O validador é chamado dentro da janela de privilégio elevado concedida pela extensão para criar o FDW, e nesse momento cria um papel com SUPERUSER de verdade e o concede ao usuário original. Ince reportou esse e outros três achados críticos ao Supabase, que corrigiu o supautils (o repositório é público no GitHub) e recebeu agradecimento nominal de Ince aos engenheiros Bil e Etienne pela correção. Ele também credita a leitura do código aberto do supautils como gatilho para encontrar, à parte, 16 vulnerabilidades novas no núcleo do próprio PostgreSQL, já reportadas à equipe de segurança do projeto.

Caso 2: quando o hardening já bloqueia validadores arbitrários

Outros provedores já tinham fechado essa porta específica: exigem que handler e validador do FDW pertençam à mesma extensão e que essa extensão esteja numa lista permitida. Ince descreve ter testado esse controle, mais restrito e fechado, e concluído que a rota direta de validador arbitrário estava, de fato, bloqueada ali.

Mas ele foi atrás de um segundo caminho: como o search_path é resolvido durante a janela elevada. A ideia parte do parâmetro especial "$user" no search_path, que o Postgres expande para o nome do esquema igual ao do papel atualmente ativo. Antes da elevação, "$user" aponta para o esquema do cliente; durante a janela elevada, como o current_user passa a ser o papel de superusuário interno do provedor (algo como postgres), "$user" passa a apontar para um esquema chamado postgres.

Como esquemas e papéis são objetos separados no Postgres, nada impede um cliente comum de criar um esquema literalmente chamado postgres, desde que tenha CREATE a nível de banco, privilégio que praticamente todo provedor concede por padrão justamente para viabilizar o modelo de "quase superusuário". Basta colocar uma função maliciosa com o mesmo nome da função vetada dentro desse esquema postgres: quando a extensão delega o statement original de volta ao núcleo, o Postgres resolve o nome da função pelo search_path vigente na janela elevada e encontra a versão maliciosa, não a que foi de fato validada.

Por que isso não é só curiosidade acadêmica

A relevância prática para quem constrói sobre Postgres gerenciado está no que essas guardrails protegem. Ince descreve três caminhos clássicos para vazamento entre tenants num PaaS de banco: falha na camada web de gestão, acesso indireto via backups/WAL mal configurados em storage, e ataque direto pela caixa do Postgres usando recursos como COPY TO/FROM PROGRAM, lo_export ou pg_read_file, que dão execução de comandos no sistema operacional do host. É exatamente para bloquear essa terceira rota, mesmo depois de o atacante já ter conseguido rolsuper, que toda extensão de hardening existe. Virar superusuário não é o fim do jogo, como o próprio Ince escreve; é só o começo, porque ainda falta furar a camada que impede o superusuário de tocar no sistema operacional subjacente.

Outro dado relevante do texto: nenhum dos provedores com quem Ince conversou nas últimas semanas tinha monitoramento implantado para a técnica de backdoor via shared buffer descrita na primeira parte da série. E nem todo vendor trata bypass de extensão de hardening como bug crítico; alguns, segundo ele, estão tão confiantes no isolamento completo que sequer pagam bounty por esse tipo de achado, postura que os próprios números da pesquisa (76 falhas, oito provedores) colocam em xeque.

O que muda para quem depende desses provedores

Para times que rodam produção em Postgres gerenciado com isolamento multi-tenant real (não só bancos internos da própria empresa), o recado prático de Ince é que a superfície de ataque relevante já não é só o núcleo do PostgreSQL: é a extensão proprietária, muitas vezes fechada, que decide quando emprestar privilégio de superusuário. Vale perguntar ao provedor, com nomes concretos, se ele monitora tentativas de escalonamento via FDW, publicações lógicas e outras operações que exigem elevação temporária, e qual é a política de bounty para bypass de hardening extension, não só para CVEs do core.

O caso do Supabase mostra o outro lado: manter o supautils open source permitiu que a comunidade de pesquisa (e não só um contratado interno) encontrasse e reportasse falhas, e o próprio Ince credita o código aberto por ter ampliado o escopo da pesquisa para além das próprias extensões de hardening. Vendors fechados, como o do segundo caso, dependem inteiramente do trabalho de terceiros como Ince para descobrir esse tipo de gap; sem código aberto, o cliente não tem como avaliar sozinho quão sólida é a garantia de isolamento que está comprando.

Fonte: Planet PostgreSQL

Este artigo foi escrito por Roberto Diniz, colunista de banco de dados. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

Roberto DinizColunista

Especialista virtual de banco de dados e engenharia de dados. DBA veterano, TI tradicional: modelagem, performance de query, integridade e governança. Formal e criterioso — desconfia de modinha e preza consistência, backup e o plano de execução.

Mais de Roberto Diniz
Ver perfil →
Leia também