No Postgres, as consultas preparadas e as funções definidas pelo usuário são equivalentes como um mecanismo de proteção contra a injeção de SQL ?
Existem vantagens particulares em uma abordagem em relação à outra?
fonte
No Postgres, as consultas preparadas e as funções definidas pelo usuário são equivalentes como um mecanismo de proteção contra a injeção de SQL ?
Existem vantagens particulares em uma abordagem em relação à outra?
Depende.
Com LANGUAGE sql
, a resposta é geralmente sim .
Os parâmetros passados são tratados como valores e a injeção de SQL não é possível - desde que você não chame funções inseguras do corpo e passe parâmetros.
Com LANGUAGE plpgsql
, a resposta é normalmente sim .
No entanto , o PL / pgSQL permite SQL dinâmico, onde parâmetros (ou partes) passados são concatenados em uma sequência de consultas e executados com EXECUTE
. Esta pode converter a entrada do usuário para o código SQL e faz a injeção de SQL possível . Você não pode dizer de fora se o corpo da função lida com isso adequadamente. Ferramentas são fornecidas.
Use apenas SQL dinâmico onde for necessário. Instruções SQL simples usando parâmetros como valores são seguras contra injeção de SQL, como funções SQL.
Para SQL dinâmico , passe preferencialmente valores como valores com:
USING
cláusula. Exemplo .Torna a injeção de SQL impossível no principal.
Se você concatenar valores na cadeia SQL, use:
Agrupa seqüências de caracteres entre aspas simples com segurança, evitando erros de sintaxe e injeção de SQL.
Parâmetros do processo que devem ser tratados como identificadores na cadeia SQL com:
format()
com especificador de formato%I
. Exemplo .quote_ident()
. Exemplo .regclass
para nomes de tabela: _tbl::regclass
. Exemplo .Inclui seqüências de caracteres entre aspas duplas com segurança quando necessário , evitando erros de sintaxe e injeção de SQL.
Relacionado:
Nunca apenas crie uma string a partir da entrada do usuário e execute. Isso inclui identificadores, passados diretamente por um usuário ou buscados em um catálogo do sistema. Tudo tem que ser tratado como entrada do usuário e citado com segurança ao criar SQL dinâmico!
Mais sobre implicações de desempenho nesta resposta relacionada:
Noções básicas sobre injeção de SQL:
Considerações semelhantes se aplicam a outras linguagens do servidor que permitem SQL dinâmico.
USING
cláusula para passar valoresEXECUTE
sempre que possível. Você pode chamar uma função PL / pgSQL de dentro de uma função SQL e passar parâmetros. Portanto, para estar absolutamente correto, você estará seguro, desde que não chame nenhuma função insegura direta ou indiretamente. Se todas as suas funções forem executadas corretamente, isso não poderá acontecer.