Impressões sobre o RejectConf SP 2007

Posted by Leonardo Mon, 19 Nov 2007 07:10:28 GMT

Neste fim de semana, aconteceu o RejectConf SP 2007 e eu tive o prazer de estar presente. Dezenas de pessoas interessadas em Rails compareceram ao evento e ouviram palestras sobre os mais diversos assuntos.

O Akita abriu a conf contando um pouco da trajetória do Ruby e do Rails do início até os dias atuais. Falou do conceito de menos é mais, empregado pela 37 signals, empresa de onde surgiu o framework Rails. Sobre este conceito, recomendo a leitura do livro Getting Real(traduzido), e assistir esta palestra, feita por um professor de psicologia, explicando o paradoxo da escolha.

RSpec foi outro assunto que me interessou bastante. Apesar de ter sido um pouco rápido, o Danilo Sato conseguiu mostrar na prática um exemplo usando rspec com rails. Na minha opinião, o rspec deve crescer bastante e, talvez, ser mais utilizado que o xUnit. Para quem tem dúvidas sobre se vale a penas investir no assunto, veja o que Dave Astels tem a dizer nesta palestra.

Apesar de já ter lido alguma coisa sobre o JRuby, não tinha tido a oportunidade de mexer com ele ainda. Por isso, achei bem legal ver o Fabio Kung, da Caelum, mostrar as possibilidades de integração do Ruby com o Java. Com certeza, as implementações do JRuby e do IronRuby abrirão muitas portas para o Ruby. Vamos ficar de olho nelas :-)

Pra fechar, o Carlos Brando fez uma palestra muito motivadora nos chamando para a ação. Falou sobre inércia e comodismo, que são fatais para o desenvolvimento de qualquer pessoa.

Resumo da ópera: o evento foi excelente e todos os palestrantes estão de parabéns. Ficou claro para mim que Rails já não é mais brincadeira, e sim uma realidade no mercado brasileiro, e a tendência é aumentar. Para quem ainda não vê benefícios nem tem curiosidades em Rails, acho que deveriam olhar o assunto com mais calma.

O próximo evento que participarei será o RioOnRails, no dia 8/dez. Sei também que haverá o MinasOnRails no dia 1/dez, mas infelizmente, não poderei ir.

Posted in  | Tags ,  | 2 comments

Interface de administração

Posted by Leonardo Thu, 16 Aug 2007 11:43:50 GMT

É muito provavél que você já tenha precisado fazer um módulo de administração para os modelos da sua aplicação. Pois é, eu também. A primeira coisa que me veio a cabeça foi usar o famoso scaffold. Sabe aquela coisa: "Ah, isso não tem tanta importância agora e depois eu faço bonitinho". Acontece que a gente nunca volta para refazer nada.

Então, resolvi ver o que as outras pessoas estavam fazendo com relação a interfaces de administração e encontrei 3 plugins que podem adiantar a vida de qualquer um. São eles:

Não cheguei a instalar todos, mas pelos sites, os dois primeiros parecem estar mais desenvolvidos. O que eles trazem de vantagens sobre o scaffold comum é que além de ter uma apresentação muito mais agradável, eles conseguem manipular associações entre os modelos e permitem customizações da interface de forma declarativa.

Se você tem um ambiente de administração restrito, onde o essencial é fazer o CRUD dos seus modelos, um desses plugins pode ser uma excelente pedida.

Posted in  | Tags , ,  | 2 comments

habtm ou has_many :through?

Posted by Leonardo Sun, 12 Aug 2007 20:41:07 GMT

Há alguns dias atrás, precisei criar uma associação m x n e fiquei na dúvida entre usar o has_and_belongs_to_many ou o has_many :through. Como sabia que o primeiro era o modo antigo de se fazer esse tipo de associações, e o segundo o "novo", fui pesquisar um pouco mais para saber qual dos dois iria usar.

Habtm

O habtm funciona muito bem quando se quer apenas uma associação simples, sem um modelo associado a essa tabela de relacionamento. Por associação simples, quero dizer que a tabela de relacionamento não possui mais nenhum campo além dos ids das tabelas relacionadas.

Has_many :through

Se quisermos ter informações adicionais na tabela de relacionamento ou um modelo onde podemos ter controle sobre os relacionamentos, então o has_many :through é o caminho a seguir.

A escolha acabou se tornando simples após essa pesquisa. Se tiver um relacionamento simples, escolha a primeira representação. Caso contrário, use a segunda.

Outra coisa importante de se destacar é que, se você quiser seguir o estilo REST, escolha o has_many :through porque, através do modelo criado, é possível expor o CRUD para esse relacionamento.

Posted in  | Tags ,  | no comments

Suas aplicações rails são seguras? (sql injection)

Posted by Leonardo Tue, 07 Aug 2007 22:33:22 GMT

SQL Injection é um problema comum de ocorrer se não tivermos cuidado com as informações vindas dos usuários, geralmente através de formulários. Um usuário malicioso poderia, por exemplo, tentar ter acesso a um cadastro manipulando o formulário de login de uma aplicação.

A seguir, criarei um cenário de login onde as informações vindas do formulário poderão ser manipuladas para ganhar acesso a aplicação, e depois, mostrarei como podemos evitar essa falha.

Este poderia ser um controller de autorização:

class User < ActiveRecord::Base
  def login
    @user = User.find(:first, 
                 :conditions => "login = '#{params[:name]}' 
                 AND password = '#{params[:password]}'")
  end
end

Isso é perigoso porque o símbolo # substitui a váriável diretamente pelo valor, sem nenhum tratamento. Então, se um usuário entrasse com o seguinte nome e senha:

params[:name] = ' OR '1'='1
params[:password] = ' OR '1'='1

geraria esta consulta no banco:

select * from users where login='' OR '1'='1' AND
                          password='' OR '1'='1' LIMIT 1

Com essa consulta, o usuário entraria no site com o login do primeiro usuário cadastrado no banco. Como a cláusula OR sempre será true, é como se fizéssemos o select sem cláusula where e isto retornaria a tabela inteira, mas com o LIMIT 1, apenas o primeiro usuário será retornado. Muitas vezes esse usuário pode ser até o administrador.

Para resolver essa falha, reescreveremos o método de login assim:

  def login
    @user = User.find(:first, 
            :conditions => ["login = ? AND password = ?"
            ,params[:name],params[:password]])
  end

Veja que agora passamos a condição via array sendo o primeiro índice a condição propriamente dita e, a partir do segundo índice, as variáveis, já tratadas pelo Rails, que serão substituídas pelo símbolo ? na mesma ordem que os símbolos aparecem.

Com isso, podemos entrar com aqueles valores anteriores que não haverá problemas, pois os caracteres especiais foram tratados.

Posted in ,  | Tags ,  | 3 comments

Suas aplicações rails são seguras? (mass assignment)

Posted by Leonardo Thu, 02 Aug 2007 20:27:39 GMT

Mass assignment é uma ferramenta muito poderosa que o ActiveRecord nos fornece. Com ela, podemos criar um objeto, passando todas as informações de um formulário, simplesmente com uma linha de código. Mas, sem tomar as devidas precauções, podemos nos encrencar feio criando falhas de segurança na aplicação.

Vejamos um exemplo simples de como isso pode acontecer. Suponha que tenhamos esse migration:

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.column :name, :string
      t.column :admin, :boolean
    end
  end

  def self.down
    drop_table :users
  end
end

esse controller:

class UserController < ApplicationController
  def create
    @user = User.create(params[:user])
  end
end

e esse view:

<form method="post" action="/user/create">
  <input type="text" name="user[name]" />
</form>

Tudo pronto e funcionando. Até que de repente, alguém resolver brincar um pouco com os dados do formulário e submete um form com os seguintes dados:

<form method="post" action="/user/create">
  <input type="text" name="user[name]" />
  <input type="hidden" name="user[admin]" value="1" />
</form>

Pronto. O usuário agora também é um administrador e pode fazer coisas desastrosas.

Podemos resolver isso dizendo para o model quais são os campos protegidos e que serão ignorados pelo mass assignment.

class User < ActiveRecord::Base
  attr_protected :admin
end

Outra forma de resolver o problema, é dizendo para o model quais são os campos permitidos para mass assignment.

class User < ActiveRecord::Base
  attr_accessible :name
end

A diferença entre as duas abordagens é, que na primeira, os campos são permitidos por default e somente os campos listados são protegidos, enquanto que na segunda acontece justamente o contrário.

Particularmente, acho a segunda abordagem mais segura, porque, se criarmos mais campos posteriormente, eles estarão protegidos por default.

A seguir, falarei de SQL Injection.

Posted in ,  | Tags ,  | no comments

Older posts: 1 2