O token de autenticidade é usado para impedir ataques de falsificação de solicitação entre sites (CSRF). Para entender o token de autenticidade, você deve primeiro entender os ataques CSRF.
CSRF
Suponha que você é o autor de bank.com
. Você tem um formulário em seu site usado para transferir dinheiro para uma conta diferente com uma solicitação GET:
Um hacker pode simplesmente enviar uma solicitação HTTP para o servidor dizendo GET /transfer?amount=$1000000&account-to=999999
, certo?
Errado. O ataque dos hackers não funcionará. O servidor vai pensar basicamente?
Hã? Quem é esse cara tentando iniciar uma transferência. Não é o proprietário da conta, com certeza.
Como o servidor sabe disso? Porque não há session_id
cookie para autenticar o solicitante.
Quando você entra com seu nome de usuário e senha, o servidor define um session_id
cookie no seu navegador. Dessa forma, você não precisa autenticar cada solicitação com seu nome de usuário e senha. Quando o navegador envia o session_id
cookie, o servidor sabe:
Oh, esse é John Doe. Ele fez login com sucesso há 2,5 minutos. Ele está pronto para ir.
Um hacker pode pensar:
Hmm. Uma solicitação HTTP normal não funcionará, mas se eu pudesse colocar minha mão naquele session_id
cookie, seria dourado.
O navegador do usuário possui vários cookies configurados para o bank.com
domínio. Toda vez que o usuário faz uma solicitação ao bank.com
domínio, todos os cookies são enviados. Incluindo o session_id
cookie.
Portanto, se um hacker conseguir que você faça a solicitação GET que transfere dinheiro para a conta dele, ele será bem-sucedido. Como ele poderia induzi-lo a fazer isso? Com falsificação de solicitação entre sites.
É bem simples, na verdade. O hacker pode levá-lo a visitar o site dele. Em seu site, ele poderia ter a seguinte tag de imagem:
<img src="http://bank.com/transfer?amount=$1000000&account-to=999999">
Quando o navegador dos usuários encontrar essa tag de imagem, ele fará uma solicitação GET para esse URL. E, como a solicitação vem do navegador, ela envia todos os cookies associados bank.com
. Se o usuário tiver entrado recentemente em bank.com
... o session_id
cookie será definido e o servidor pensará que o usuário pretendia transferir US $ 1.000.000 para a conta 999999!
Bem, apenas não visite sites perigosos e você ficará bem.
Isso não basta. E se alguém postar essa imagem no Facebook e ela aparecer no seu mural? E se for injetado em um site que você está visitando com um ataque XSS?
Não é tão ruim. Somente solicitações GET são vulneráveis.
Não é verdade. Um formulário que envia uma solicitação POST pode ser gerado dinamicamente. Aqui está o exemplo do Guia de Segurança do Rails :
<a href="http://www.harmless.com/" onclick="
var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = 'http://www.example.com/account/destroy';
f.submit();
return false;">To the harmless survey</a>
Token de Autenticidade
Quando você ApplicationController
tem isso:
protect_from_forgery with: :exception
Este:
<%= form_tag do %>
Form contents
<% end %>
É compilado para isso:
<form accept-charset="UTF-8" action="/" method="post">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
Form contents
</form>
Em particular, o seguinte é gerado:
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
Para se proteger contra ataques CSRF, se o Rails não vir o token de autenticidade enviado junto com uma solicitação, ela não considerará a solicitação segura.
Como um invasor deve saber o que é esse token? Um valor diferente é gerado aleatoriamente cada vez que o formulário é gerado:
Um ataque de Cross Site Scripting (XSS) - é assim. Mas essa é uma vulnerabilidade diferente para um dia diferente.