Blue Medora é um serviço para encaminhar métricas de monitoramento do Postgres para o Google Cloud Monitoring.
Como parte de suas instruções de configuração, eles oferecem um script SQL para configurar um usuário com privilégios mínimos a ser usado para fazer login na conta. (colado abaixo para referência)
Se a conta bluemedora fosse comprometida, que informação poderia vazar ou o que mais poderia fazer?
(obviamente substituindo tmppassword
no script é um dado)
Uma óbvia é que ele pode extrair todas as estatísticas sobre as quais relata, incluindo consultas de relatórios que estão sendo executadas, o que pode levar ao vazamento de PII se estiver incluído nessas consultas.
Com base nas informações presentes, um invasor pode descobrir os nomes dos usuários e superusuários do banco de dados, todas as tabelas sendo usadas e com as consultas provavelmente uma boa parte das estruturas das tabelas. Que poderia então ser usado para criar um ataque direcionado.
Existem outras formas mais diretas de acessar os dados armazenados nas tabelas com essa conta ou escalar privilégios?
Aqui está o roteiro
CREATE SCHEMA bluemedora;
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
CREATE OR REPLACE FUNCTION bluemedora.pg_stat_statements() RETURNS SETOF pg_stat_statements AS
$$
SELECT * FROM public.pg_stat_statements;
$$ LANGUAGE sql VOLATILE SECURITY DEFINER;
CREATE OR REPLACE FUNCTION public.explain_this (
l_query text,
out explain json
)
RETURNS SETOF json AS
$$
BEGIN
RETURN QUERY EXECUTE 'explain (format json) ' || l_query;
END;
$$
LANGUAGE 'plpgsql'
VOLATILE
RETURNS NULL ON NULL INPUT
SECURITY DEFINER
COST 100 ROWS 1000;
CREATE USER bluemedora WITH PASSWORD 'tmppassword';
GRANT SELECT ON pg_database TO bluemedora;
GRANT SELECT ON pg_stat_bgwriter TO bluemedora;
GRANT SELECT ON pg_stat_database TO bluemedora;
GRANT SELECT ON pg_stat_user_indexes TO bluemedora;
GRANT SELECT ON pg_stat_user_tables TO bluemedora;
GRANT SELECT ON pg_statio_all_sequences TO bluemedora;
GRANT SELECT ON pg_statio_user_indexes TO bluemedora;
GRANT SELECT ON pg_statio_user_tables TO bluemedora;
GRANT SELECT ON pg_tables TO bluemedora;
GRANT SELECT ON pg_tablespace TO bluemedora;
GRANT SELECT ON pg_user TO bluemedora;
GRANT SELECT ON pg_stat_replication TO bluemedora;
GRANT SELECT ON pg_stat_database_conflicts TO bluemedora;
GRANT SELECT ON pg_trigger TO bluemedora;
GRANT SELECT ON pg_stat_activity TO bluemedora;
GRANT SELECT ON pg_stat_statements TO bluemedora;
GRANT USAGE ON SCHEMA bluemedora TO bluemedora;
GRANT EXECUTE ON FUNCTION public.explain_this(l_query text, out explain text) TO bluemedora;
O grande problema de segurança aqui é que ele não revoga a execução em suas funções criadas de PUBLIC, o que significa que outros usuários além do bluemedora podem usá-las, o que evidentemente não é o pretendido. Para pg_stat_statement isso não é realmente um problema, pois está localizado em um esquema ao qual ninguém mais deve ter acesso, mas para explain_this está em esquema público e com direitos de execução PUBLIC. E por que o explain_this é criado em público em primeiro lugar? Se há uma razão para distribuir as funções em dois esquemas, não sei qual é. Parece que talvez o explain_this foi adicionado ao script por alguém que não sabia o que estava fazendo.
A concessão de SELECT em todas essas tabelas de catálogo é desnecessária na maioria das instalações, pois aquelas já possuem SELECT concedido para PUBLIC. No entanto, não há garantia de que este script será executado na "maioria das instalações", portanto, é razoável conceder explicitamente essas permissões em vez de depender de alguém que não tenha alterado os padrões. O mais preocupante para mim seria a falta de qualificação de esquema nessas bolsas.
Todas essas coisas, exceto o texto da consulta, serão verdadeiras para quase qualquer usuário comprometido, mesmo sem permissões especiais concedidas. Você está preocupado com ataques de engenharia social?