SQL Injection em ADVPL: Como me proteger?

Aloha!

Sou o Arthur Fücher e nesse meu primeiro post venho falar de um assunto bem crítico e que possui uma forma bem tranquila de ser tratado: SQL Injection.

O que é SQL Injection?

SQL Injection, ou Injeção SQL, é uma falha onde é possível injetar código SQL dentro de uma consulta que o sistema executa no Banco de Dados.

Para entender melhor vamos imaginar o seguinte cenário:

Temos uma aplicação com uma tela simples de login: Usuário, Senha e um botão de Login. Ao clicar no botão a aplicação pega o valor das variáveis de user e password e monta a consulta para executar no banco da seguinte maneira:

"SELECT * 
 FROM users 
 WHERE username = '"+ user +"' AND password = '"+ password + "'"

Supondo que a pessoa digitou meu_usuario e a senha 123, teremos a seguinte consulta:

SELECT * 
FROM users 
WHERE username = 'meu_usuario' AND password = '123'

Agora vamos supor que uma pessoa má intencionada digite no lugar campo de user o seguinte valor: ‘ OR 1=1–, parece um texto sem sentido certo?? Mas vamos ver como que ficaria na nossa consulta:

SELECT * FROM users WHERE username = '' OR 1=1--' AND password = '123'

 

Veja que foi injetado na consulta um OR 1 =1, com isso ela sempre retornará resultados e mesmo sem validar usuário e senha o login será feito! :O

Prepared Statement

Para evitar essa injeção podemos utilizar o conceito de Prepared Statement, onde montamos uma consulta pré-definida, e depois injetamos somente os parâmetros que são alteráveis nela. Com isso os parâmetros são tratados individualmente, evitando a injeção.

Para identificar os parâmetros, substituímos seus valores pelo caractere ‘?’.

Para exemplificar vou mostrar como ficaria nossa consulta:

SELECT * FROM users WHERE username=? AND password=?

Para se beneficiar do Prepared Statement em AdvPL basta utilizar a classe FWPreparedStatement

//Inicializa as variáveis
oStatement := FWPreparedStatement():New()
cQuery := "SELECT * FROM users WHERE username=? AND password=?"
//Define a consulta e os parâmetros
oStatement:SetQuery(cQuery)
oStatement:SetString(1,cUser)
oStatement:SetString(1,cPassword)
//Recupera a consulta já com os parâmetros injetados
cFinalQuery := oStatement:GetFixQuery()

Se passarmos os mesmos parâmetros do exemplo, teremos o seguinte resultado:

SELECT * FROM users WHERE username=''' OR 1=1--' AND password='123'

Obs.: Este é um exemplo bem simples, sabemos que por exemplo senhas não devem ser gravadas diretas no banco. O intuito é apenas demonstrar o uso de Prepared Statement para evitar SQL Injection.


Espero que esse post tenha sido útil!

Até breve!

 

 

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s