Um dos maiores problemas que assombram os desenvolvedores de software é o SQL Injection. Essa técnica pode permitir que um código SQL seja executado através da aplicação cliente sem qualquer tipo de restrição e, assim, alterar os dados sem qualquer conhecimento dos administradores do sistema. Parece grave, certo? E, realmente, é. Sendo assim, neste artigo falaremos um pouco sobre o SQL Injection e como proteger aplicações Python deste tipo de ataque.
O problema
Como dito anteriormente, o SQL Injection permite que código SQL seja executado através da aplicação cliente diretamente no banco de dados. Isso permite que hackers consigam alterar dados de forma irrestrita e sem consentimento dos administradores do sistema, o que é um problema muito grave em relação a segurança de um sistema. Para entender melhor este problema, vamos a um exemplo prático.
Imagine uma aplicação simples em que seja possível atualizar clientes passando seu nome e idade. Focando apenas no back-end da aplicação e sem qualquer tipo de verificação de SQL Injection, o código responsável por atualizar clientes seria basicamente da seguinte forma:
nome = 'João'
cursor.execute(f"UPDATE cliente SET nome={nome} WHERE idcliente=13")
O código acima irá atualizar o nome do cliente com id 13 para “João”. Até aí, tudo bem. Estamos apenas atualizando o nome de um cliente em nosso banco de dados. Porém, imagine que, ao invés de passar apenas ‘João’ para a variável nome, passarmos um código SQL:
nome = "'Carlos' , idade = 80"
cursor.execute(f"UPDATE cliente SET nome={nome} WHERE idcliente=13")
O código acima permitirá que o nome e idade do cliente com id 13 sejam alterados simultaneamente, sem permissão ou consentimento do administrador do sistema. Até pode paracer bobagem não permitir a edição da idade de um cliente, porém, imagine um sistema bancário com este mesmo problema e que permita que o valor do saldo seja alterado pelo usuário… Complicou, né?
A solução
Para solucionar o problema do SQL Injection, precisamos parametrizar as querys utilizadas em nosso programa e, assim, não permitir que um código SQL seja executado pelo lado cliente da aplicação. Para isso, alteramos a query da seguinte forma:
nome = "'Carlos' , idade = 80"
cursor.execute("UPDATE cliente SET nome=%(nome)s WHERE idcliente=13", ({'nome': nome, }))
Com o código acima, não vamos mais executar o código presente na variável "nome"
no UPDATE. Ao invés disso, todo o conteúdo desta variável será armazenado como nome do cliente com id 13
. Fazendo com que, o nome do cliente com id 13
seja "Carlos, idade = 80"
e a sua idade permaneça inalterada.
Concluindo
Desta forma, não vamos mais permitir que os campos de uma determinada tabela sejam alterados sem permissão do sistema e, assim, garantimos muito mais segurança para a nossa aplicação.