Segurança da sua aplicação e os frameworks: o ataque ao GitHub

Quanto é necessário conhecer as suas ferramentas para garantia a segurança de sua aplicação?

Egor Homakov fez barulho durante o fim de semana. O russo realizou um commit no branch master do repositório do Rails, passando parâmetros a mais no formulário de registro de chaves públicas do Github, algo conhecido como injeção por parâmetros, dado o recurso de mass assignement do Rails. Homakov fez o ataque de forma muito simples, uma vez que ele inferiu que existia um modelo na aplicação chamado PublicKey e que o mesmo possuía relacionamento com a classe User. Com isso, ele adicionou um campo novo no formulário, para indicar quem é o dono de tal chave pública. Isso foi feito através de um input type="hidden" value="USER_ID" name="public_key[user_id]".

Formulário de cadastro de chave pública no Github

Formulário de cadastro de chave pública no Github

Bastou submeter o formulário com o novo campo e o valor adequado, para que o usuário possuísse a chave pública que estava sendo cadastrada.

Ataque ao Github

Imagem que mostra o resultado do ataque ao Github

A resposta do GitHub, assim como a atitude de suspender o usuário, foi duramente criticada por alguns desenvolvedores, sendo revertida poucas horas depois.

Mas não é só o Rails que possui essa, digamos, facilidade-vulnerabilidade. O Spring já tinha uma issue registrada para isso e o Sergio Lopes já alertou sobre esse problema de injeção de parâmetros no modelo.

A solução no Rails é simples, mas pode ser facilmente esquecida e ignorada. Basta declararmos que não queremos que um determinado atributo seja populado pelo request, como numa lista negra:

  attr_protected :user_id

Apesar dessa forma funcionar, você pode simplesmente esquecer de marcar como protected um atributo novo, adicionado ao modelo. A forma ideal seria declarar todos os atributos que podem ser massivamente modificados, uma white list, caso o atributo não esteja marcado dessa forma, ele não será atualizado:

  attr_accessible :name

Uma outra questão: de quem fica a responsabilidade nesse caso? O framework deveria permitir apenas white lists para popular objetos via request? Ou o desenvolvedor deveria sempre ficar atento a esses casos? De qualquer maneira, é mais um alerta de que sempre precisamos dominar o framework que utilizaremos.

12 Comentários

  1. Roberto Souza 05/03/2012 at 11:56 #

    Assim até eu hackeio :). Perigoso mesmo, kkkk. parabéns pelo artigo.

  2. Phil Calçado 05/03/2012 at 12:59 #

    O framework peopular um objeto baseado em um HTTP request não é o problema, o problema é que no caso do post do Sérgio (e exemplo no site do VRaptor) e em aplicações ActiveRecord/Rails você não tem objetos, têm estruturas de dados burras que aceitam qualquer coisa sem validar contratos.

  3. Roger Almeida 05/03/2012 at 13:24 #

    IMHO grande parte do problema é o fato de a api(https://api.github.com/users/rails) do github expor, por exemplo, o ID interno do usuário. Esse dado não deveria ser público…

  4. Bruno Laturner 05/03/2012 at 13:29 #

    “De quem fica a responsabilidade nesse caso?”

    A responsabilidade deveria ser da equipe que fez o framework, que deixa opções perigosas em aberto ao seus desenvolvedores-usuários, que se fosse assim, que pelo menos escondessem a opção mais perigosa de sua documentação, e usassem a opção mais segura em seus tutoriais.
    Desta forma desenvolvedores não seriam levados ao erro.

    Foi este o pensamento que tive quando li o artigo pela primeira vez. E traí o que acredito:

    Desenvolvedores medíocres que precisam ser protegidos deveriam estar fora do mercado.

    Por nossa própria segurança.

    É pura falta de profissionalismo da pessoa não ler e entender a especificação de um framework antes de usá-lo; não saber se o sistema web desenvolvido consegue se defender dos ataques mais comuns; dar desculpas que tudo é muito complexo. Não é novidade que tudo é muito complexo. Ou devo dar boas vindas?

    Não duvido da capacidade da equipe do GitHub, imagino que estejam no nível dos melhores (mais fé que evidências), e sinceramente, merda acontece. Mas quantos outros que trabalham com Rails nem sabem o que attr_accessible e attr_protected fazem? Que saíram copiando e colando códigos online?

    E voltamos naquela velha discussão de por que não deixamos um médico despreparado fazer uma cirurgia em nós, mas contratamos empresas pelo menor valor para cuidar de sistemas de milhões?

  5. Sérgio Lopes 05/03/2012 at 14:12 #

    A responsabilidade é do programador. Ele precisa entender que uma classe de modelo no Rails/VRaptor/Struts/etc é um white-list de campos. Só se coloca lá o que se permite popular.

    É impossível um framework saber automaticamente quais campos podem e quais nao podem ser submetidos. Aliás, acho ridículo o pessoal acusando o Rails de ter um bug; Definitivamente não é culpa do Rails.

    E falando nisso, o DHH postou como ele faz os white lists de atributos nos sistemas dele em Rails: https://gist.github.com/1975644

  6. Thiago Nuic 05/03/2012 at 20:54 #

    Sem dúvida a responsabilidade é do programador. Documentação de boas práticas não falta. Um exemplo de como fazer isso existe no railscasts faz tempo, que inclusive tem versão mais nova: http://railscasts.com/episodes/237-dynamic-attr-accessible

  7. Renato 06/03/2012 at 02:09 #

    Eu que venho do .net e usava frameworks bem menos produtivos não sabia dessa modalidade e ataque, que faz todo sentido. Ainda bem que foi um ataque que não causou dano e fez com que muita se liasse nesse aspecto. Muito bacana o seu post e do Sérgio.

  8. AmBAr Amarelo 06/03/2012 at 19:48 #

    A culpa é do framework que não pensou no “fator humano”.

  9. diego 09/03/2012 at 09:56 #

    Seria legal no QCon 2012 ter uma palestra sobre segurança e performance em Rails.
    😉

  10. Guilherme Garnier 14/03/2012 at 13:31 #

    Se o pessoal do GitHub acompanhasse meu blog, não teria passado por esse problema 😀

    http://blog.guilhermegarnier.com/2011/11/rails-e-mass-assignment-como-aumentar-a-seguranca-dos-atributos/

  11. Caio Ribeiro Pereira 14/04/2012 at 17:15 #

    Estou recentemente usando BitBucket e adorei ele, até agora nenhuma ocorrência de sérios bugs que aconteceu com github e ganho 5 repositórios privados de graça!

Deixe uma resposta