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