Injeção de SQL nas funções do Postgres x consultas preparadas

30

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?

mickeyf_supports_Monica
fonte

Respostas:

36

Depende.

Funções SQL

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.

Funções PL / pgSQL

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:

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:

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.

Erwin Brandstetter
fonte
Portanto, em resumo: se 1) eu uso apenas o idioma sql, estou seguro, 2) se eu uso o plpgslq, mas não o executo, estou seguro, 3) se eu uso o plpgsql e o executo, mas não identificadores e% s ou% L, conforme apropriado, estou seguro, ou 4) se eu usar plpgsql e executar e identificadores, mas% I ou quote_ident, conforme apropriado, estou seguro. Corrigir?
mickeyf_supports_Monica
@mickeyf: Basicamente sim. Além disso, use a USINGcláusula para passar valores EXECUTEsempre 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.
Erwin Brandstetter