Evitando Inject SQL Com Rails

Bem Pessoal,

Hoje iremos falar de como evitar injeções SQL com Rails.

Vamos dizer que temos uma tabela de usuario com os seguintes campos:

#Tabela Usuario

* id- Integer
* Nome – Varchar(255)
* Login – Varchar(255)
* Senha – Varchar(255)
* Admin – Boolean

E temos uma pagina do nosso site para buscar usuarios pelo o nome na nossa base de dados.

Nosso Modelo Usuario:

#model

class Usuario < ActiveRecord::Base
end

Então temos no nosso UsuarioController o seguinte:

#controller
class UsuarioController < ApplicationController
def buscaUsuario
if params[:nome]
@usuarios = Usuario.find(:all,:conditions=>"nome like '%#{params[:nome]}%'")
else
@usuarios = Usuario.find(:all)
end
end
end

E na view referente ao action buscarUsuario:

#view
<%=form_tag %>
<%=text_field_tag "nome",nil %>
<%=submit_tag "Buscar"%>
<% for usuario in @usuarios%>
<% end %>
<%=usuario.nome%>
<%=end_form_tag %>

Então, basicamente temos um input, onde é digitado o nome do usuario, e o sistema mostra uma lista de usuarios que possui o que foi digitado no nome do usuario.

Ex.: Matos

resultado:

* Italo Matos
* Ronaldo Matos
* Matos José

O resultado está Ok. Então o que está errado ? Não é que a implementação esteja errado, mas com essa implementação abrimos furos na aplicação, e se tivermos um usuario malicioso, pode se aproveitar desses furos.


...
@usuarios = Usuario.find(:all,:conditions=>"nome like '%#{params[:nome]}%'")
...

Acima temos implementação feita no nosso controller. Vamos digitar no input a palavra Matos então será gerado a seguinte consulta SQL:

SELECT * FROM usuarios WHERE (nome like ‘%Matos%’ )

Certo , até ai tudo bem.

Agora vamos dizer que o usuário digitou no input %’ and admin = 1 and ‘%%’ = ‘% Então , qual a consulta será gerada? a resposta logo abaixo:

SELECT * FROM usuarios WHERE (nome like ‘%%’ and admin = 1 and ‘%%’ = ‘%%’)

Ai é onde mora o perigo, ele irá listar todos os administradores do sistema, independente do nome. Isso dai que é chamado de injeção SQL. Conseguiu injectar codigo SQL em uma consulta, onde na verdade a consulta seria somente para buscar um usuario com um determinado nome.

Para previnirmos desses ataques, trocaremos no nosso controller:

@usuarios = Usuario.find(:all,:conditions=>"nome like '%#{params[:nome]}%'")

Por:

@usuarios = Usuario.find(:all,:conditions=>["nome like ?","%"+params[:nome]+"%"])

Agora vamos ver como ficou a consulta SQL:

SELECT * FROM usuarios WHERE (nome like ‘%%’ and admin = 1 and ‘%%’ = ‘%%’)

ele o rails colocou as antes das aspas simples em que digitamos no input, assim nos previnimos das injeções SQL.

em consulta a banco de dados, deixe o framework tratar essas injeções.

Até a próxima pessoal.

Explore posts in the same categories: Uncategorized

Deixe uma resposta

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

WordPress.com Logo

You are commenting using your WordPress.com account. Sair / Alterar )

Imagem do Twitter

You are commenting using your Twitter account. Sair / Alterar )

Foto do Facebook

You are commenting using your Facebook account. Sair / Alterar )

Connecting to %s


Seguir

Obtenha todo post novo entregue na sua caixa de entrada.