Em que ordem o PostgreSQL verifica as permissões do objeto?

16

Dada uma função de banco de dados user1, uma função something()definida como um procedimento armazenado e uma exibição criada como:

CREATE VIEW view1 AS select * from something()

E, dadas essas permissões:

REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1

Quando corro SELECT * FROM view1, recebo um erro permission denied for function something().

Minha pergunta é, se eu revogar as permissões de seleção na exibição, por que a função é chamada? Eu esperava receber algo como:

permission denied for relation view1

Obrigado!

santios
fonte
2
AFAIK não há uma ordem definida na qual as permissões são verificadas.
Craig Ringer
@CraigRinger Obrigado! Acho que esse é o comportamento esperado então. Como eu estou expondo a exibição em uma API, eu estava tentando evitar revelar detalhes de implementação da exibição (dada a mensagem de erro reclamando das permissões da função em vez da exibição).
Santios 5/05
11
Eu suspeitaria que as permissões sejam avaliadas da mesma forma que os planos de consulta de moda (por exemplo, de baixo para cima) e, como tal, o objeto mais baixo é avaliado primeiro, o que, no seu caso, é a something()função. Um teste rápido seria modificar a consulta para obter um plano de explicação diferente, ajustando as permissões de acordo e ver se o erro de permissão é gerado na something()função ou se segue como o novo plano de execução está sendo reavaliado.
John Eisbrener
Se você conceder permissões para a função e revogá-las na exibição, ele deve omitir qualquer menção à função subjacente
amenadiel 13/18

Respostas:

3

O problema nesse caso não é exatamente sobre ordem de permissão, mas ordem de execução.

Em resumo, para o PostgreSQL:

1- As visualizações que estão acessando tabelas substituirão a permissão das tabelas

2- As visualizações que acessam funções, precisarão avaliar todas as funções, antes de serem verificadas - para que as funções sejam executadas antes de acessar a visualização, mesmo que a visualização não possua permissões de seleção ...

Como podemos provar isso?

No postgresql, as visualizações podem lhe dar permissões para fazer uma seleção em uma tabela, mesmo se o usuário não tiver essas permissões.

Por exemplo:

create view view2 as select * from table1;
revoke all on table1 from user1;
grant select on view2 to user1; 

Efetue login como usuário 1:

select * from table1 (permission denied) 
select * from view2 (sucess - the query executes)

No caso, o usuário poderá selecionar a view2, mesmo sem ter permissão para selecionar a tabela.

Mas e se fizermos a mesma coisa com uma função ? O comportamento NÃO é o mesmo. Vamos criar uma função que aguarde 5 segundos antes de retornar 1 (para que possamos depurar se o postgresql estiver executando a função toda vez que chamamos de view)

CREATE OR REPLACE FUNCTION something() RETURNS integer
AS 'select 1 from pg_sleep(5);'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT; --this function will delay 5 seconds

create view view1 as select * from something();
revoke all on function something() from user1;
grant select on view1 to user1; 

Efetue login como usuário 1:

select * from something(); (permission denied for something) 
select * from view1 (permission denied for something )

A permissão para selecionar na exibição não substitui a permissão da função e, pior ainda, se revogarmos as permissões da view1, a mensagem ainda mostra que o postgresql interrompeu nossa consulta devido à função, independentemente da permissão da exibição. (é exatamente isso que está acontecendo na pergunta)

Mas a função está realmente sendo verificada primeiro? Se dermos as permissões 'all' à função, mas revogar a permissão de visualização ...

grant all on function something to user1; 
revoke all on view1 from user1; 
select * from view1;
Delayed 5 seconds... (the function executed!) 
Permission denied for select on view1

Como você vê no postgresql, esperei 5 segundos antes de dizer que não temos permissão para exibir a exibição , mostrando que a função "something ()" é executada. Portanto, o retorno dos dados da função deve existir antes da verificação da visualização.

Portanto, agora com esses testes, sabemos agora que o PostgreSQL precisava primeiro avaliar todas as funções antes de continuar nossa consulta, é como a consulta ainda não existe até que todas as funções envolvidas sejam totalmente concluídas, portanto a visualização não pode ser resolvida para o postgresql. saber se temos ou não permissão para selecioná-lo.

Eu acho que isso responde à sua pergunta nos termos de "ordem de permissão", mas por que o postgresql precisa avaliar todas as funções antes de continuar, isso é outra questão ...

777Anon
fonte