É verdade que os procedimentos armazenados impedem ataques de injeção de SQL nos bancos de dados PostgreSQL? Eu fiz uma pequena pesquisa e descobri que o SQL Server, Oracle e MySQL não são seguros contra injeção de SQL, mesmo se usarmos apenas procedimentos armazenados. No entanto, esse problema não existe no PostgreSQL.
A implementação do procedimento armazenado no núcleo do PostgreSQL evita ataques de injeção de SQL ou é outra coisa? Ou o PostgreSQL também é suscetível à injeção de SQL, mesmo se usarmos apenas procedimentos armazenados? Se sim, por favor, mostre-me um exemplo (por exemplo, livro, site, jornal, etc.).
postgresql
security
sql-injection
Am1rr3zA
fonte
fonte
Respostas:
Não, os procedimentos armazenados não impedem a injeção de SQL. Aqui está um exemplo real (de um aplicativo interno criado por alguém onde eu trabalho) de um procedimento armazenado que infelizmente permite a injeção de SQL:
Este código do servidor sql:
aproximadamente equivalente ao postgres:
A idéia do desenvolvedor era criar um procedimento de pesquisa versátil, mas o resultado é que a cláusula WHERE pode conter tudo o que o usuário desejar, permitindo a visita de pequenas tabelas de Bobby .
Se você usa instruções SQL ou procedimento armazenado, não importa. O que importa é se o seu SQL usa parâmetros ou seqüências de caracteres concatenadas. Parâmetros impedem injeção de SQL; seqüências concatenadas permitem injeção de SQL.
fonte
Os ataques de injeção de SQL são aqueles em que as entradas não confiáveis são consultas diretamente anexadas, permitindo que o usuário efetivamente execute código arbitrário, conforme ilustrado neste quadrinho XKCD canônico.
Assim, entendemos a situação:
Os procedimentos armazenados são, em geral, boas defesas contra ataques de injeção SQL, porque os parâmetros recebidos nunca são analisados.
Em um procedimento armazenado, na maioria dos bancos de dados (e programas, não se esqueça que as consultas pré-compiladas contam como procedimentos armazenados) se parecem com o seguinte:
Então, quando o programa deseja acessar, ele chama
foo(userInput)
e recupera o resultado com satisfação.Um procedimento armazenado não é uma defesa mágica contra a injeção de SQL, pois as pessoas conseguem escrever procedimentos armazenados incorretos . No entanto, as consultas pré-compiladas, sejam elas armazenadas no banco de dados ou no programa, são muito mais difíceis de abrir brechas de segurança se você entender como o SQL-Injection funciona.
Você pode ler mais sobre SQL-Injection:
fonte
Sim, até certo ponto.
Somente os procedimentos armazenados não impedirão a injeção de SQL.
Deixe-me citar primeiro sobre a injeção de SQL da OWASP
É necessário limpar as entradas do usuário e não concatenar instruções SQL, mesmo se você estiver usando o procedimento armazenado.
Jeff Attwood explicou as consequências da concatenação do sql em " Dê-me SQL parametrizado ou dê-me a morte "
A seguir, apresentamos o desenho interessante que sempre me ocorre quando ouço o SQL Injection , acho que você entendeu :-)
Dê uma olhada na Folha de Batalha de Prevenção de Injeção de SQL , os métodos de prevenção são bem explicados ...
fonte
A concatenação de cadeias é a causa da injeção de SQL. Isso é evitado usando a parametrização.
Os procedimentos armazenados adicionam uma camada adicional de segurança ao impor sintaxe inválida ao concatenar, mas não são "mais seguros" se você usar, digamos, SQL dinâmico neles.
Portanto, seu código acima é causado pela concatenação dessas cadeias
exec sp_GetUser '
x' AND 1=(SELECT COUNT(*) FROM Client); --
' , '
monkey
'
Isso fornece sintaxe inválida, felizmente
Parametrizar daria
Isso significa
@UserName
=x' AND 1=(SELECT COUNT(*) FROM Client); --
@Password
=monkey
Agora, no código acima, você não terá linhas porque presumo que você não tem usuário
x' AND 1=(SELECT COUNT(*) FROM Client); --
Se o processo armazenado tiver esta aparência (usando SQL dinâmico concatenado ), sua chamada de procedimento armazenado parametrizado ainda permitirá a injeção de SQL
Portanto, como demonstrado, a concatenação de strings é o principal inimigo da injeção de SQL
Os procedimentos armazenados adicionam encapsulamento, manipulação de transações, permissões reduzidas etc., mas ainda podem ser abusados pela injeção de SQL.
Você pode procurar no Stack Overflow para saber mais sobre parametrização
fonte
"Ataques de injeção SQL acontecer quando a entrada do usuário é indevidamente codificado. Normalmente, a entrada do usuário é alguns dados o usuário envia com sua consulta, valores ou seja, no
$_GET
,$_POST
,$_COOKIE
,$_REQUEST
, ou$_SERVER
matrizes. No entanto, a entrada do usuário também pode vir de uma variedade de outros fontes, como soquetes, sites remotos, arquivos, etc. Portanto, você realmente deve tratar tudo, menos as constantes (como'foobar'
) como entrada do usuário ".Estive investigando minuciosamente esse assunto recentemente e gostaria de compartilhar com outras pessoas um material bastante interessante, tornando assim este post mais completo e instrutivo para todos.
Do YouTube
Da Wikipedia
De OWASP
Do manual do PHP
Da Microsoft e Oracle
Estouro de pilha
Scanner de injeção SQL
fonte
Os procedimentos armazenados não impedem magicamente a injeção de SQL, mas facilitam muito a prevenção. Tudo o que você precisa fazer é algo como o seguinte (exemplo do Postgres):
É isso aí! O problema só surge ao formar uma consulta por meio de concatenação de strings (ou seja, SQL dinâmico) e, mesmo nesses casos, você pode vincular! (Depende do banco de dados.)
Como evitar a injeção de SQL na sua consulta dinâmica:
Etapa 1) Pergunte a si mesmo se você realmente precisa de uma consulta dinâmica. Se você está juntando as cordas apenas para definir a entrada, provavelmente está fazendo algo errado. (Existem exceções a essa regra - uma exceção é para relatar consultas em alguns bancos de dados; você pode ter problemas de desempenho se não forçar a compilação de uma nova consulta a cada execução. Mas pesquise esse problema antes de pular para isso. )
Etapa 2) Pesquise a maneira correta de definir a variável para seu RDBMS específico. Por exemplo, o Oracle permite que você faça o seguinte (citando seus documentos):
Aqui você ainda não está concatenando a entrada. Você está vinculando com segurança! Viva!
Se seu banco de dados não suportar algo como o descrito acima (espero que nenhum deles ainda seja tão ruim, mas não ficaria surpreso) - ou se você ainda precisar concatenar sua entrada (como no caso "às vezes" de relatar consultas como Eu sugeri acima), então você deve usar uma função de escape adequada. Não escreva você mesmo. Por exemplo, o postgres fornece a função quote_literal (). Então você executaria:
Dessa forma, se in_name for algo desonesto como '[snip] ou 1 = 1' (a parte "ou 1 = 1" significa selecionar todas as linhas, permitindo que o usuário veja salários que ele não deveria!), Então quote_literal salva sua bunda por fazendo a sequência resultante:
Nenhum resultado será encontrado (a menos que você tenha alguns funcionários com nomes realmente estranhos).
Essa é a essência disso! Agora, deixe-me deixar um link para um post clássico do guru do Oracle, Tom Kyte, sobre o SQL Injection, para esclarecer o assunto: Linky
fonte
quote_ident()
- mas, em geral, a maneira mais fácil de escrever SQL dinâmico à prova de injeção é usarformat()
e usar os espaços reservados%I
para identificadores e%L
literais. Dessa forma, o SQL é muito mais legível do que a versão equivalente usando||
equote_....()
funções