Prevenção de ataques CSRF e XSRF

Em Cross-Site Request Forgeries e o senhor Eu pedi aos desenvolvedores a observarem atentamente as possíveis vulnerabilidades de CSRF / XSRF em seus próprios sites. Elas são o pior tipo de vulnerabilidade: muito fáceis de serem exploradas pelos invasores, mas não tão intuitivamente fáceis de entender pelos desenvolvedores de software, pelo menos até que o senhor seja mordido por uma delas.

No Blog Freedom to Tinker, Bill Zeller oferece uma das melhores e mais concisas explicações sobre o XSRF que já li até hoje:

As vulnerabilidades de CSRF ocorrem quando um site permite que um usuário autenticado execute uma ação sensível, mas não verifica se o próprio usuário está invocando essa ação. A chave para entender os ataques de CSRF é reconhecer que os sites normalmente não verificam se uma solicitação veio de um usuário autorizado. Em vez disso, eles verificam apenas se a solicitação veio do navegador de um usuário autorizado. Como os navegadores executam códigos enviados por vários sites, existe o perigo de um site (sem o conhecimento do usuário) enviar uma solicitação a um segundo site, e o segundo site pensar erroneamente que o usuário autorizou a solicitação.

Esse é o elemento-chave para entender o XSRF. Os invasores estão apostando que os usuários têm um cookie de login validado para o seu site já armazenado no navegador. Tudo o que eles precisam fazer é fazer com que esse navegador faça uma solicitação ao seu site em nome deles. Se eles conseguirem:

  1. Convencer seus usuários a clicar em uma página HTML que eles construíram
  2. Inserir HTML arbitrário em um site de destino que seus usuários visitam

O jogo da XSRF está em andamento. Não é muito difícil, não é?

Bill Zeller e Ed Felten também identificaram novas vulnerabilidades XSRF em quatro grandes sites há menos de duas semanas:

  1. ING Direct

    Descobrimos vulnerabilidades de CSRF no site do ING que permitiam que um invasor abrisse contas adicionais em nome de um usuário e transferisse fundos da conta de um usuário para a conta do invasor.

  2. YouTube

    Descobrimos vulnerabilidades de CSRF em quase todas as ações que um usuário pode realizar no YouTube.

  3. MetaFiltro

    Descobrimos uma vulnerabilidade de CSRF no MetaFilter que permitia que um invasor assumisse o controle da conta de um usuário.

  4. The New York Times

    Descobrimos uma vulnerabilidade de CSRF no NYTimes.com que torna os endereços de e-mail dos usuários disponíveis para um invasor. Se o senhor for um membro do NYTimes.com, sites arbitrários podem usar esse ataque para determinar seu endereço de e-mail e usá-lo para enviar spam ou para identificá-lo.

Se os principais sites voltados para o público estão sendo vítimas dessas graves explorações de XSRF, qual é o grau de confiança que o(a) senhor(a) tem de que o senhor o senhor não cometeu os mesmos erros? Pense com cuidado. Estou dizendo isso como um desenvolvedor que já cometeu esses mesmos erros em seu próprio site. Sou tão culpado quanto os outros.

É nosso trabalho garantir que os futuros desenvolvedores não repitam os mesmos erros estúpidos que cometemos, pelo menos não sem lutar. O artigo de Felten e Zeller (pdf) recomenda o método “double-submitted cookie” para evitar o XSRF:

Quando um usuário visita um site, o site deve gerar um valor pseudoaleatório (criptograficamente forte) e defini-lo como um cookie no computador do usuário. O site deve exigir que cada envio de formulário inclua esse valor pseudo-aleatório como um valor de formulário e também como um valor de cookie. Quando uma solicitação POST é enviada para o
o site, a solicitação só deve ser considerada válida se o valor do formulário e o valor do cookie forem os mesmos. Quando um invasor envia um formulário em nome de um usuário, ele só pode modificar os valores do formulário. Um invasor não pode ler nenhum dado enviado pelo servidor nem modificar os valores do cookie, de acordo com a política de mesma origem. Isso significa que, embora um invasor possa enviar o valor que quiser com o formulário, ele não poderá modificar ou ler o valor armazenado no cookie. Como o valor do cookie e o valor do formulário devem ser os mesmos, o invasor não conseguirá enviar um formulário com êxito, a menos que consiga adivinhar o valor pseudoaleatório.

A vantagem dessa abordagem é que ela não exige nenhum estado do servidor; o senhor simplesmente define o valor do cookie uma vez e, em seguida, cada HTTP POST verifica se um dos valores de <input> enviados contém exatamente o mesmo valor de cookie. Qualquer diferença entre os dois significa um possível ataque XSRF.

Um método de prevenção ainda mais forte, embora mais complexo, é aproveitar o estado do servidor. para gerar (e rastrear, com tempo limite) uma chave aleatória exclusiva para cada FORM HTML que o senhor enviar ao cliente. Usamos uma variante desse método no Stack Overflow com grande sucesso. É por isso que em cada <form> o senhor verá o seguinte:

<input id="fkey" name="fkey" type="hidden" value="df8652852f139" />

Se o senhor quiser auditar um site em busca de vulnerabilidades XSRF, comece fazendo esta pergunta simples sobre cada formulário HTML que encontrar: “Onde está o valor XSRF?”