Apenas olhando para:
(Fonte: https://xkcd.com/327/ )
O que esse SQL faz:
Robert'); DROP TABLE STUDENTS; --
Conheço os dois '
e faço --
comentários, mas a palavra DROP
também não é comentada, pois faz parte da mesma linha?
security
validation
sql-injection
Blankman
fonte
fonte
'
não é para comentários . Mesmo se fosse, não há espaço antes dele, para que ele possa terminar apenas a sequência que o precede.Respostas:
Deixa cair a mesa dos alunos.
O código original no programa da escola provavelmente se parece com
Esta é a maneira ingênua de adicionar entrada de texto em uma consulta e é muito ruim , como você verá.
Depois que os valores do primeiro nome, a caixa de texto do nome do meio FNMName.Text (que é
Robert'); DROP TABLE STUDENTS; --
) e o sobrenome da caixa de texto LName.Text (vamos chamá-loDerper
) são concatenados com o restante da consulta, o resultado agora é na verdade duas consultas separadas pelo terminador de instrução (ponto e vírgula). A segunda consulta foi injetada na primeira. Quando o código executa essa consulta no banco de dados, ele se parecerá com esteque, em inglês simples, se traduz aproximadamente nas duas consultas:
e
Tudo após a segunda consulta é marcado como um comentário :
--', 'Derper')
O
'
nome do aluno não é um comentário, é o delimitador da string de fechamento . Como o nome do aluno é uma sequência, é necessário sintaticamente para concluir a consulta hipotética. Os ataques de injeção funcionam apenas quando a consulta SQL injetada resulta em SQL válido .Editado novamente de acordo com o comentário astuto de dan04
fonte
INSERT
, então o parêntese faria mais sentido. Também explicaria por que a conexão com o banco de dados não está no modo somente leitura.INSERT
. Pensando de trás para frente,SELECT
ele não funcionaria de qualquer maneira, já que a Inserção das Mesinhas Bobby na mesa já teria largado a mesa.Students
espera mais do que apenas uma coluna (a instrução original / correta forneceu duas colunas). Dito isto, a presença da segunda coluna é útil para mostrar por que os comentários são necessários; e como não se pode mudar o nome de Bobby, provavelmente é melhor deixar como está com pouco mais do que essa observação como nota de rodapé.Digamos que o nome foi usado em uma variável
$Name
,.Você então executa esta consulta :
O código está colocando erroneamente qualquer coisa que o usuário tenha fornecido como variável.
Você queria que o SQL fosse:
Mas um usuário inteligente pode fornecer o que quiser:
O que você recebe é:
O
--
único comenta o restante da linha.fonte
Como todo mundo já apontou, o documento
');
fecha a declaração original e, em seguida, segue uma segunda declaração. A maioria das estruturas, incluindo linguagens como PHP, já possui configurações de segurança padrão que não permitem várias instruções em uma string SQL. No PHP, por exemplo, você só pode executar várias instruções em uma sequência SQL usando amysqli_multi_query
funçãoNo entanto, você pode manipular uma instrução SQL existente via injeção SQL sem precisar adicionar uma segunda instrução. Digamos que você tenha um sistema de login que verifique um nome de usuário e uma senha com esta simples seleção:
Se você fornecer
peter
como nome de usuário esecret
senha, a sequência SQL resultante será semelhante a esta:Está tudo bem. Agora imagine que você forneça essa sequência como a senha:
Então a string SQL resultante seria esta:
Isso permitiria que você efetue login em qualquer conta sem saber a senha. Portanto, você não precisa usar duas instruções para usar a injeção SQL, embora possa fazer coisas mais destrutivas se conseguir fornecer várias instruções.
fonte
Não,
'
não é um comentário no SQL, mas um delimitador.Mamãe supôs que o programador de banco de dados fez uma solicitação parecida com:
(por exemplo) para adicionar o novo aluno, onde o
$xxx
conteúdo da variável foi retirado diretamente de um formulário HTML, sem verificar o formato nem escapar caracteres especiais.Portanto, se
$firstName
contiverRobert'); DROP TABLE students; --
o programa de banco de dados, executará a seguinte solicitação diretamente no banco de dados:ie ele encerrará precocemente a instrução de inserção, executará o código malicioso que o cracker desejar e depois comentará o restante do código que houver.
Mmm, eu sou muito lento, já vejo 8 respostas antes da minha na faixa laranja ... :-) Parece um tópico popular.
fonte
TL; DR
Isso elimina (exclui) a tabela do aluno.
( Todos os exemplos de código nesta resposta foram executados em um servidor de banco de dados PostgreSQL 9.1.2. )
Para deixar claro o que está acontecendo, vamos tentar isso com uma tabela simples contendo apenas o campo de nome e adicionar uma única linha:
Vamos supor que o aplicativo use o seguinte SQL para inserir dados na tabela:
Substitua
foobar
pelo nome real do aluno. Uma operação de inserção normal ficaria assim:Quando consultamos a tabela, obtemos o seguinte:
O que acontece quando inserimos o nome de Little Bobby Tables na tabela?
A injeção de SQL aqui é o resultado do nome do aluno encerrando a instrução e incluindo um
DROP TABLE
comando separado ; os dois traços no final da entrada devem comentar qualquer código restante que, de outra forma, causaria um erro. A última linha da saída confirma que o servidor de banco de dados descartou a tabela.É importante observar que, durante a
INSERT
operação, o aplicativo não verifica os caracteres especiais da entrada e, portanto, permite que entradas arbitrárias sejam inseridas no comando SQL. Isso significa que um usuário mal-intencionado pode inserir, em um campo normalmente destinado à entrada do usuário, símbolos especiais como aspas e código SQL arbitrário para fazer com que o sistema de banco de dados o execute, daí a injeção de SQL .O resultado?
A injeção de SQL é o equivalente ao banco de dados de uma vulnerabilidade de execução remota de código arbitrário em um sistema operacional ou aplicativo. O impacto potencial de um ataque de injeção SQL bem-sucedido não pode ser subestimado - dependendo do sistema de banco de dados e da configuração do aplicativo, ele pode ser usado por um invasor para causar perda de dados (como neste caso), obter acesso não autorizado a dados ou até mesmo executar código arbitrário na própria máquina host.
Conforme observado pelo quadrinho do XKCD, uma maneira de proteger contra ataques de injeção de SQL é higienizar as entradas do banco de dados, como escapar caracteres especiais, para que eles não possam modificar o comando SQL subjacente e, portanto, não possam causar a execução de código SQL arbitrário. Se você usar consultas parametrizadas, como
SqlParameter
no ADO.NET, a entrada será, no mínimo, higienizada automaticamente para proteger contra injeção de SQL.No entanto, a limpeza das entradas no nível do aplicativo pode não parar as técnicas mais avançadas de injeção de SQL. Por exemplo, existem maneiras de contornar a
mysql_real_escape_string
função PHP . Para proteção adicional, muitos sistemas de banco de dados suportam instruções preparadas . Se implementadas corretamente no back-end, as instruções preparadas podem impossibilitar a injeção de SQL tratando as entradas de dados como semanticamente separadas do restante do comando.fonte
Digamos que você escreveu ingenuamente um método de criação de alunos como este:
E alguém entra no nome
Robert'); DROP TABLE STUDENTS; --
O que é executado no banco de dados é esta consulta:
O ponto e vírgula termina o comando de inserção e inicia outro; o - comenta o resto da linha. O comando DROP TABLE é executado ...
É por isso que os parâmetros de ligação são uma coisa boa.
fonte
Uma aspas simples é o início e o fim de uma sequência. Um ponto e vírgula é o fim de uma declaração. Então, se eles estavam fazendo uma seleção como esta:
O SQL se tornaria:
Em alguns sistemas, o
select
primeiro seria executado, seguido peladrop
instrução! A mensagem é: NÃO INCORPORAR VALORES NO SEU SQL. Em vez disso, use parâmetros!fonte
Ao
');
final da consulta, ele não inicia um comentário. Em seguida, ele solta a tabela de alunos e comenta o restante da consulta que deveria ser executada.fonte
O escritor do banco de dados provavelmente fez uma
Se student_name é o escolhido, a seleção é feita com o nome "Robert" e a tabela é descartada. A parte "-" altera o restante da consulta fornecida em um comentário.
fonte
Nesse caso, 'não é um caractere de comentário. É usado para delimitar literais de strings. O artista de quadrinhos está apostando na idéia de que a escola em questão possui sql dinâmico em algum lugar que se parece com isso:
Então agora o caractere 'termina a string literal antes que o programador a estivesse esperando. Combinado com o; Para encerrar a declaração, um invasor agora pode adicionar o sql que desejar. O comentário - no final é para garantir que qualquer sql restante na instrução original não impeça a compilação da consulta no servidor.
FWIW, também acho que o quadrinho em questão tem um detalhe importante errado: se você está pensando em higienizar as entradas do banco de dados, como sugere o quadrinho, ainda está fazendo errado. Em vez disso, você deve pensar em termos de quarentena de suas entradas de banco de dados, e a maneira correta de fazer isso é através de consultas parametrizadas.
fonte
O
'
caractere no SQL é usado para constantes de seqüência de caracteres. Nesse caso, é usado para finalizar a constante da string e não para comentar.fonte
Funciona assim: suponha que o administrador esteja procurando registros de alunos
Como a conta de administrador possui privilégios elevados, é possível excluir a tabela desta conta.
O código para recuperar o nome de usuário da solicitação é
Agora, a consulta seria algo assim (para pesquisar na tabela do aluno)
A consulta resultante se torna
Como a entrada do usuário não é higienizada, a consulta acima é manipulada em 2 partes
O traço duplo (-) comentará apenas a parte restante da consulta.
Isso é perigoso, pois pode anular a autenticação de senha, se presente
O primeiro fará a pesquisa normal.
O segundo eliminará o aluno da tabela se a conta tiver privilégios suficientes (geralmente a conta de administrador da escola executará essa consulta e terá os privilégios mencionados acima).
fonte
SELECT* FROM sutdents ...
- você esqueceu um "s". Isto é o que você está deixando cair.DROP TABLE STUDENTS;
Você não precisa inserir dados do formulário para fazer a injeção de SQL.
Ninguém apontou isso antes, então posso alertar alguns de vocês.
Principalmente tentaremos corrigir a entrada de formulários. Mas este não é o único lugar onde você pode ser atacado com injeção de SQL. Você pode fazer um ataque muito simples com a URL que envia dados através da solicitação GET; Considere o seguinte exemplo:
Seu URL seria http://yoursite.com/show?id=1
Agora alguém poderia tentar algo como isto
Tente substituir table_name pelo nome da tabela real. Se ele acertar o nome da sua mesa, eles esvaziarão a sua mesa! (É muito fácil forçar essa URL com um script simples)
Sua consulta seria mais ou menos assim ...
Exemplo de código vulnerável do PHP usando o PDO:
Solução - use os métodos prepare () e bindParam () do PDO:
fonte