Estou seguro contra injeção de SQL
-
06-07-2019 - |
Pergunta
Eu gostaria de saber se eu estou seguro contra injeção de SQL quando eu usar algo parecido com PostgresSQL:
CREATE or REPLACE FUNCTION sp_list_name( VARCHAR )
RETURNS SETOF v_player AS '
DECLARE
v_start_name ALIAS FOR $1;
r_player v_player%ROWTYPE;
v_temp VARCHAR;
BEGIN
v_temp := v_start_name || ''%'';
FOR r_player IN
SELECT first_name, last_name FROM v_player WHERE last_name like v_temp
LOOP
RETURN NEXT r_player;
END LOOP;
RETURN;
END;
' LANGUAGE 'plpgsql' VOLATILE;
Eu quero usar essa função para o nome início lista do jogador com uma carta.
select * from sp_list_name( 'A' );
me dá jogadores com sobrenome começando com A.
Eu tentei injetar sql com
select * from sp_list_name( 'A; delete from t_player;--' );
select * from sp_list_name( '''; delete from t_player;--' );
Am I seguro?
O que caso eu poderia ser injetado?
Saudações
Solução
Em termos de seu procedimento você parece seguro como a variável no SP não será expandida dentro do código, mas você ainda pode expor a si mesmo se você não usar uma consulta parametrizada como " SELECT * FROM sp_list_name(?);
"em sua código appplication . Algo como " SELECT * FROM sp_list_name('$start_name');
" poderia ser subvertida por um usuário passar um nome de início de " ');delete from t_player where last_name NOT IN ('
". Portanto, use uma consulta parametrizada ou sanidade verificar suas entradas em seu programa.
Nota: Para outros, por favor nota que uma variável em um procedimento armazenado não expandir em código mesmo se ele contém um "ou;, (excluindo passá-la para Executar , para o qual você usaria quote_literal
, não-mão rolou replace
funções) para a substituição; ou "é totalmente desnecessário (no procedimento armazenado, o aplicativo usando é uma história diferente, é claro) e iria impedi-lo de sempre encontrar o 'tl;dr
' ou equipas 'O'Grady
'.
Leo Moore, Karl, LFSR Consulting : v_temp_name
no procedimento armazenado irá não ser expandida em código no SP (sem Executar ) , a verificação precisaria ser feito n o aplicativo, não o SP (ou o OP poderia usar apenas uma consulta parametrizada em seu código do aplicativo, em vez disso). O que os outros estão sugerindo é semelhante a se preocupar com
my $bar = "foo; unlink('/etc/password');";
my $baz = $bar;
realmente executar o unlink na ausência de um eval.
Outras dicas
Rule # 1 para prevenir contra injeção de SQL: Sanitize todas as entradas que é proveniente de alguém / algo que você não pode confiar / não tem controle sobre.
O problema em si não se encontra dentro do código de banco de dados, mas a partir da aplicação que está a executar essas declarações.
A maneira correta de proteger contra SQL Injection é via Branco Listing * - o longo e curto é definir os caracteres que você vai aceitar e filtrá-los.
A maneira incorreta é Lista Negra - Black listando quais caracteres não são aceitos é vai levar a problemas, porque não pode manter-se com os atacantes. Existem maneiras de contornar listas negras através de tabelas ASCII, caracteres de escape e quais não.
Além disso, aqui está uma boa Cheat Sheet para experimentar em seu site. Fazer alguns testes e tentar fazer as coisas a falhar.
*
Na aplicação, não o DB (Graças James)
Você não está gerando SQL para si mesmo, tão seguro (para mim), esta aparência.
Eu não sei de onde os dados que você está chamando o procedimento armazenado está vindo. Então você ainda tem que se proteger contra tampão transborda etc.
Ref. Listagem branco. Este é OK, se certas outras condições forem seguidas. É absolutamente imperativo para quebrar todas as entradas para baixo na forma mais simples é tão não basta buscar por nomes de consulta SQL, aspas simples etc. Eles podem ser representadas ou codificados usando outros conjuntos de caracteres e é isso que faz parte da lista branca não especificamente palavras-chave SQL si.
Eu estava trabalhando para um determinado cliente que permitiu usuário / senha para um recurso protegido (que em última análise poderia conseguir-lhe um passe de acesso em partes seguras de um aeroporto!). Você poderia contornar o campo logon digitando 'e, em seguida, a construção de consultas SQL de lá para recuperar as contas de usuário e senhas.
O problema foi que o cliente já tinha explodido £ 200k construção do site com um fornecedor que parecia ter desenvolvimento web nunca feito antes. A correção foi um adicional de £ 60k que era uma func validate () que só foi a verificação de união, selecione, tendo et al palavras-chave. Quando perguntado sobre o que eles fizeram para canicolisation / codificação (o que eu tinha que, em seguida, explicar) que era hora tumbleweed.
A casa Dev eo (caro) Projeto foi enlatada.
Você poderia considerar validar o conteúdo de
v_start_name. Verifique a string para dois pontos semi, comentário caracteres, iguais, etc. Lembre-se de verificar para ambos os Chars e os valores Hex. Lembre-se de permitir um nome com hífen, por exemplo, 'Smith-Brown' é provavelmente aceitável. 'Smith - Brown' é potencialmente injeção
Se não estiver familiarizado com Hex no SQL Injection A seguir, são introduções rápidas
http: // www .arejae.com / blog / sql-injeção-ataque utilizando-t-sql-and-hexadecimal.html
http://www.securityfocus.com/infocus/1768
DECLARE v_start_name ALIAS FOR $1; r_player v_player%ROWTYPE; v_temp VARCHAR; BEGIN -- new pseudo code here if v_start_name has bad chars exit with error message -- end pseudo code here v_temp := v_start_name || ''%''; FOR r_player IN SELECT first_name, last_name FROM v_player WHERE last_name like v_temp LOOP RETURN NEXT r_player; END LOOP; RETURN; END;
Saudações Karl
Basta fazer uma substituição no seu v_start_name para se livrar da ";" etc. ie
v_clean_name VARCHAR;
Select v_clean_name = Replace(v_start_name,';','');
Este irá substituir o; com espaços em branco frustrando um ataque injecção SQL
Para mais detalhes veja Funções para String em PostgresSQL
Como LFSR Consulting também comentou. É melhor WhiteList (ou seja, não processar qualquer entrada com caracteres inválidos como um ';'). Invés de BlackList (ou seja, tente limpar os dados como o usuário poderia fazer um ataque de injeção SQL em seu Substitua também)
Para mais informações dê uma olhada no noreferrer ataques de injeção SQL