Desde 9.2, é possível usar o security_barrier
atributo para proteger contra funções escolhidas maliciosamente e operadores que acessam dados 'ocultos' por trás de filtros em visualizações (informações completas na documentação do postgres ).
Você pode ver isso acontecendo no teste abaixo, mas o mesmo efeito não é observado com a função set-return em vez de uma visualização no final do teste.
Isso é apenas uma peculiaridade deste teste individual ou as funções de retorno são sempre uma maneira segura de se proteger contra esse tipo de vazamento?
banco de ensaio:
create schema stack;
set search_path=stack;
create table t(secret) as values (1), (2);
teste1:
create view v as select * from t where secret^4>1;
select * from v;
/*
┌────────┐
│ secret │
├────────┤
│ 2 │
└────────┘
*/
create function f(integer) returns integer cost 1 language plpgsql as $$
begin
raise notice 'secret is: %',$1;
return $1;
end;
$$;
select * from v where f(secret)>0;
/*
NOTICE: secret is: 1 <-------- SECURITY LEAK
NOTICE: secret is: 2
┌────────┐
│ secret │
├────────┤
│ 2 │
└────────┘
*/
teste2:
create function fv() returns setof t language sql as $$
select * from t where secret^4>1
$$;
select * from fv() where f(secret)>0;
/*
NOTICE: secret is: 2 <-------- no leak
┌────────┐
│ secret │
├────────┤
│ 2 │
└────────┘
*/
limpar:
drop schema stack cascade;
1 Existem razões de desempenho pelas quais você pode não querer seguir este caminho, mesmo que seja seguro
Sim - se você usar funções em um idioma diferente de
SQL
, ou se as definir comoSTRICT
.Essencialmente, você deve evitar o inlining da função. Se a função não estiver embutida, os predicados não poderão ser empurrados para baixo e ela não poderá ser nivelada.
Somente funções SQL são elegíveis para inlining e somente se não forem definidas como
STRICT
.