SQL INJECTION

O QUE É SQL INJECTION (SQLI)? o SQL injection ou SQLI, é uma das uma das vulnerabilidades mais famosas, e uma das mais perigosas tambem.

a vulnerabilidade consiste em alterar parametros usados em requisições para que o banco de dados nos devolva informações que nao deveriamos ter acesso normalmente, como: dados de outras colunas da tabela que podem ter informações sigilosas, colunas com os dados de outros usuarios, como email,senha,telefone e e.t.c. ou até outras tabelas do banco de dados.

O QUE PODE CAUSAR? como citado, o SQL injection pode nos devolver informações de outros usuários, podendo causar vazamentos de dados muito sérios e prejudiciais aos usuários e a propria impresa responsavel pelo site.

imagine o site de um banco, se o banco possuir tal vulnerabilidade, o atacante pode acessar indevidamente a conta de diversos usuarios, e fazer trasnferencias de dinheiro, compras em seu nome, emprestimos e muitos outros danos aos usuarios e ao banco, inclusive a venda dessas informações sigilosas em mercados ilegais de dados.

COMO ACONTECE A VULNERABILIDADE? (exemplos)

para entender melhor o como pode acontecer o SQL injection, seguiremos com o seguinte exemplo:


site de compras


esse é um site de compras(falso) que exibe seus produtos em diferentes categorias, e ele possui uma vulnerabilidade SQLI nesse seu mecanismo de categorias de produtos:


site de compras


note que quando clicamos na categoria de produtos "accessories", o navegador solicita a URL com category recebendo esse parametro no exemplo desse site o que acontece nessa consulta SQL é o seguinte codigo:

SELECT * FROM products WHERE category = 'accessories' AND released = 1

essa consulta SQL solicita que o banco de dados nos retorne:

  • todos os detalhes(*)
  • da tabela products
  • que a categoria é accessories
  • e *released = 1

no codigo released é uma condição responsavel por exibir apenas produtos com essa condição(released) sendo 1, podemos presumir que released = 0 são produtos ocultos, porque ainda não lançaram ou outro motivo para estarem ocultos do usuario.

sabendo que o site nao possui nem uma defesa contra SQLI e está vulneravel, o atacante poderia simplismente modificar o parametro de category na URL:


url do site de compras


note os (--), no sql isso significa de abrirá um comentario,entao, aquela mesma consulta ficaria assim:

SELECT * FROM products WHERE category = 'accessories'--' AND released = 1

após o (--), tudo será tratado como comentario, inclusive a restrição de released ser igual a 1, o que faz nos retornar os produtos ocultos:

requisição normal


site de compras normal


requisição com SQLI site de compras com SQLI


note que temos acesso a 1 produto que estava oculto. esse é um exemplo muito simplis, e pouco danoso, mas pode dar uma noção de como tudo funciona.

VAMOS CONSIDERAR OUTRO EXEMPLO


site login


esse site permite que o usuario logue com seu nome e senha.

o site verifica os dados do usuario da conta usando a seguinte consulta SQL:

SELECT * FROM users WHERE username = 'light' AND password = '1234'

a tabela onde username = "light" e password = "1234" é retornada se os dois campos forem validos.

note que username e password são os parametros para que retorne os dados da conta corretamente,se qualquer um estiver incorreto o login não acontecerá. Mas agora, se no lugar do nome colocassemos o nome de usuario e um sinal de comentario(--), o que aconteceria? Como ja vimos antes o sinal de (--) é um indicativo que tudo em seguida será comentado, o que fará o parametro da senha tambem ser comentado, assim a verificação seria baseada apenas no nome do usuario, nos dando acesso a qualquer conta sem a nessecidade da senha.

assim que a consulta SQLI se pareceria:

SELECT * FROM users WHERE username = 'light'--' AND password = '0000'

note que o invasor colocou a senha "0000"(incorreta), mas mesmo assim teria acesso a conta, ja que a verificação da senha foi comentada.

mais exemplos em breve estou um pouco oculpado agora, e nao vou conseguir me aprofundar em outros exemplos, mas para quem souber sobre, os comentarios são um otimo acrecimo ao post original, sinta-se a vontade para explicar mais:)

COMO TESTAR ATIVAMENTE: em construção

TIPOS DE SQLI E COMO CADA UM FUNCIONA: existem varios tipo de SQL injection, cada um com certas diferenças em como explora-los e como pode afetar o sistema. os principais são:

por hoje é isso:) vou tentar atualizar constantemente esse post,com mais exemplos, explorando os diferentes tipos de sqli e melhorar algo que possa estar errado ou confuso. espero que nos comentarios tambem expliquem sobre, assim criando muito conteudo para quem clicar nesse post em busca de aprender mais.

é sempre recomendavel olhar a fonte para esse post

Muito obrigado pelas informações. É interessante também ressaltar que não só uma SQL Injection pode vir de input de um usuário, mas também da própria base de dados. Porque às vezes o site faz uma verificação do input do usuário no momento de inserção, mas quando busca tais valores da base dados, é possível que estes não sejam devidamente sanitizados. A isto chamamos de Second Order SQL Injection. Por isso é importante que todo e qualquer input seja validado e sanitizado antes de ser inserido na view; não importa a origem.

obrigado por complementar essas informações ao post, ainda estou estudando sobre, então não está 100% o post, mas como disse, o intuito é atualizar e fazer outros posts relacionados. ontem postei um sobre sqli baseado em UNION, caso queira ver, ta marcado no post o link.

Muito bom, eu já tinha estudado sobre isso mas é sempre bom dar uma revisada.

Vlw pelo post LIGHTdev4687, muito bem feito!

Para que quiser treinar as tricks desse post em um ambiente real pode usar o site http://testphp.vulnweb.com/ mantido pela Acunetix, esse site é projetado para ser vulnerável a ataques web.

É muito relevante estudarmos sobre falhas de segurança de software e os diferentes tipos de vulnerabilidade que uma aplicação pode ter. Pra escrever código seguro, é fundamental, primeiro, saber os meios que alguém pode usar pra se beneficiar da falta de segurança. SQL Injection, por mais que seja simples de se proteger, ainda é uma das vulnerabilidades mais comuns hoje. É tão comum, que esta vulnerabilidade pode ser encontrada na Owasp Top 10, que é uma lista, atualizada anualmente, das vulnerabilidades mais presentes nas aplicações.

sim, o intuido é exatamente esse, apresentar essas falhas ou relembramos sobre.

Muito bom conteúdo sobre o tema, mesmo com o desenvolvimento das linguagens e algumas proteções nativas existem muitos desenvolvedores que 'esquecem do tema'. Outro item muito importante é XSS (Cross-Site Scripting)

sim, o proposito é apresentar ou relembrar que essas vulnerabilidades existem, estou trabalhando ja em outro post sobre sql injection baseado em UNION. espero concluir amanha e colocar o link nesse post.
Ótimo, quanto mais melhor! O conteúdo é super relevante para desenvolvedores enchergarem o tamanho do problema que isso pode causar rs
Acho que boa parte desses esquecimentos são causados pelos inumeros fameworks que existem e que na maior parte resolvem. Eu tava dando uma olhada em uma feature para importar dados via excel, e na parte de inserir no banco (para ficar mais rapido acredito) não tinha nenhuma verificação, então era so criar os o Excel e escrever o query desejada la dentro jsksjsksjks

Nem sabia que isso ainda funcionava. Lembro que fazia isso há 10 anos. ' or '1/' or '1

kkkkkk, um dos exemplos que eu ia botar era bem parecido com esse fazendo 1 = 1. mas decidi deixar pra depois para explicar o Boolean-Based Blind SQL Injection.

No passado um software que eu estava desenvolvendo passou por um PenTest, e a consultoria conseguiu listar todos os usuários da tabela, com todos os dados (e-mail, hash da senha, etc) manipulando a query de forma similar. Na ocasião eu usava o Laravel mas não usava o Eloquent, e dali em diante não usei mais queries raw para absolutamente nada.

Ótimo conteúdo, obrigado por compartilhar conosco! Fico no aguardo atualizações do tópico.

acabei de postar um dos tipos de sql injection: https://www.tabnews.com.br/LIGHTdev4687/sql-injection-baseado-em-union

Não sei se é realmente relevante para este material, mas a alguns dias assisti um video de um canal chamado Computerphile que falava justamente sobre o tópico:

Running an SQL Injection Attack - Computerphile

Informação importante, bom saber essas disso na hora de desenvolver. São brexas que acabam passando..

Sim, a melhor forma de se proteger é sabendo o como o invasor pensa e as técnicas que ele usa, depois vou complementar com o como se defender, soluções e e.t.c.

Esse tipo de vulnerabilidade pode estar em tantos lugares que nós nem imaginamos... Uma vez em um cliente, eu precisava de uma informação provinda de uma API do mesmo que consistia de realizar um POST e essa informação vinha no response. Entretanto eu não tinha acesso a esse POST mas sim ao GET (que em teoria traria outra informação) mas que consegui burlar ao fazer um SQL Injection através do query parameter. Foi despretencioso, mas pior que deu certo. Cuidado redobrado com nossos sistemas!

Defender-se desse tipo de ataque é bem simples. Coloque essa função "cão de guarda" nos seus programas ou em um include do php, e chame-o no início de cada página, antes de utilizar os arrays $_GET ou $_POST. Ela retira o perigoso apóstrofe de todos os parâmetros

function cao_de_guarda() {
    foreach ($_GET as $par => $valor)
    {
            $_GET[$par]=str_replace("'","", $valor);
    }

    foreach ($_POST as $par => $valor)
    {
            $_POST[$par]=str_replace("'","", $valor);
    }
}
obrigado por complementar o conteudo do post, estou apenas estudando as vulnerabilidades, por isso só apresentei o como acontece e nao como se proteger, obrigado.

Parabéns pelo post, de forma clara eu consegui realmente entender, muito show!

Até tem uma distribução Linux, o Metasploitable, que ajuda a fazer e entender como funciona SQL Injection, e outras vulnerabilidades nos sistemas. Ao rodar o sistema é possível abrir páginas web com algumas vulnerabilidades e sair testando e descobrindo como cada uma funciona.

Muito bom conteudo.

E quais seriam as formas de se proteger?

Sanitização e validação dos dados, tanto no front-end quanto no back-end é a forma mais comum de se proteger desses ataques, pois você ignora qualquer dado **não esperado** no momento da requisição.
Isso não é um problema do banco de dados, e sim da Query enviada á ele, portanto, você precisa filtrar o que vai ser enviado a ele, ou pelo menos, se certificar de que o valor bruto da String não tá sendo enviado diretamente para a Query de execução. ORM's atuais já tem proteção contra isso, mas se você estiver usando PHP, recomendo ler um pouco sobre. https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php

Isso ainda existe? lembro que eu brincava com o 'or'=1 antigamente.

acredito que funcione em muitos bancos de dados ainda, seja pela má configuração dele, nao tratar a entrada do usuario e etc. o bom é nao esquecer que essas vulnerabilidades existem.

Muito com o conteúdo, como você parece curtir essa área poderia fazer um sobre CSRF que eu usava o token para impedir no Laravel mas nunca entendi direito rs

Se existe um tipo de vulneravilidade mais famoso é esse e eu nunca tive tempo pra estudar e entender como funcion. E esse post fez eu entender perfeitamente como isso ocorre. Obrigado por compartilhar esse conteúdo!

Eu estudei SQL com MySQL e já ouvi falar dessa SQLI, mas nunca fui muito a fundo, pois não desenvolvo sites. Muito legal saber! Como é possível "encapsular" os Searchs do SQL para evitar Injections? Não precisa descrever no detalhe, pode ser resumo.

Dependendo da biblioteca existem diversas proteções. Por exemplo se vc usar mysql, e fizer tudo na mão, ao invés de construir a query concatenando parametros, é possível adicionar parametros dentro do comando mysql e depois ele mesmo substitui na query. Desta forma ele reconhece se tiver um SQLI no lugar de um parâmetro.
ORM's já possuem proteção contra isso, fique despreocupado se você utiliza Mongoose, TypeORM, etc, porém, se você escreve a Query de forma bruta colocando variáveis que o usuário modifica, aí você tem um problema. Recomendo pesquisar os métodos utilizados pela linguagem que você utiliza, um exemplo em PHP: https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php