Estou com alguns problemas relacionados ao token de autenticidade no Rails, como já fiz muitas vezes agora.
Mas eu realmente não quero apenas resolver esse problema e continuar. Eu realmente gostaria de entender o token de autenticidade. Bem, minha pergunta é: você tem alguma fonte completa de informações sobre esse assunto ou gastaria seu tempo explicando aqui em detalhes?
ruby-on-rails
ruby
authenticity-token
Ricardo Acras
fonte
fonte
Respostas:
O que acontece
Quando o usuário visualiza um formulário para criar, atualizar ou destruir um recurso, o aplicativo Rails cria um aleatório
authenticity_token
, armazena esse token na sessão e o coloca em um campo oculto no formulário. Quando o usuário envia o formulário, o Rails procuraauthenticity_token
, compara-o com o armazenado na sessão e, se corresponderem à solicitação, poderá continuar.Por que isso acontece
Como o token de autenticidade é armazenado na sessão, o cliente não pode saber seu valor. Isso impede que as pessoas enviem formulários para um aplicativo Rails sem visualizar o formulário no próprio aplicativo. Imagine que você está usando o serviço A, fez login no serviço e está tudo bem. Agora imagine que você foi usar o serviço B e viu uma foto de que gosta e pressionou a foto para vê-la em tamanho maior. Agora, se houver algum código malicioso no serviço B, ele poderá enviar uma solicitação para o serviço A (no qual você está conectado) e pedir para excluir sua conta, enviando uma solicitação para
http://serviceA.com/close_account
. Isso é conhecido como CSRF (falsificação de solicitação entre sites) .Se o serviço A estiver usando tokens de autenticidade, esse vetor de ataque não será mais aplicável, pois a solicitação do serviço B não conteria o token de autenticidade correto e não poderá continuar.
Os documentos da API descrevem detalhes sobre a metatag:
Notas
Lembre-se, o Rails apenas verifica métodos não idempotentes (POST, PUT / PATCH e DELETE). A solicitação GET não é verificada quanto ao token de autenticidade. Por quê? porque a especificação HTTP declara que as solicitações GET são idempotentes e não devem criar, alterar ou destruir recursos no servidor e a solicitação deve ser idempotentes (se você executar o mesmo comando várias vezes, deverá obter o mesmo resultado todas as vezes).
Além disso, a implementação real é um pouco mais complicada, conforme definido no início, garantindo melhor segurança. O Rails não emite o mesmo token armazenado em todos os formulários. Nem gera e armazena um token diferente sempre. Ele gera e armazena um hash criptográfico em uma sessão e emite novos tokens criptográficos, que podem ser comparados com o armazenado, toda vez que uma página é renderizada. Consulte request_forgery_protection.rb .
Lições
Use
authenticity_token
para proteger seus métodos não idempotentes (POST, PUT / PATCH e DELETE). Além disso, certifique-se de não permitir solicitações GET que possam modificar recursos no servidor.EDIT: Verifique o comentário de @erturne sobre as solicitações GET serem idempotentes. Ele explica isso de uma maneira melhor do que eu fiz aqui.
fonte
O token de autenticidade foi projetado para que você saiba que seu formulário está sendo enviado a partir do seu site. É gerado a partir da máquina na qual é executado com um identificador exclusivo que somente sua máquina pode conhecer, ajudando assim a evitar ataques de falsificação de solicitação entre sites.
Se você está simplesmente tendo dificuldades com os trilhos para negar o acesso ao script AJAX, pode usar
para gerar o token correto ao criar seu formulário.
Você pode ler mais sobre isso na documentação .
fonte
O que é CSRF?
O token de autenticidade é uma contramedida para a falsificação de solicitação entre sites (CSRF). O que é CSRF, você pergunta?
É uma maneira que um invasor pode potencialmente seqüestrar sessões sem saber os tokens de sessão.
Cenário :
Solução CSRF :
fonte
Exemplo de ataque mínimo que seria evitado: CSRF
No meu site
evil.com
, convido você a enviar o seguinte formulário:Se você estiver conectado ao seu banco através de cookies de sessão, os cookies serão enviados e a transferência será feita sem que você saiba.
Ou seja, onde o token CSRF entra em jogo:
Portanto, o formulário em um navegador autêntico seria semelhante a:
Assim, meu ataque falharia, pois não estava enviando o
authenticity_token
parâmetro, e não há como eu adivinhar, pois é um número aleatório enorme.Essa técnica de prevenção é chamada de Padrão de Token de Sincronizador .
Política de Mesma Origem
Mas e se o invasor fizer duas solicitações com JavaScript, uma para ler o token e a segunda para fazer a transferência?
O padrão de token do sincronizador por si só não é suficiente para impedir isso!
É aqui que a Política de mesma origem vem em socorro, como expliquei em: /security/8264/why-is-the-same-origin-policy-so-important/72569# 72569
Como o Rails envia os tokens
Coberto em: Rails: Como funciona o csrf_meta_tag?
Basicamente:
Ajudantes de HTML, como
form_tag
adicionar um campo oculto ao formulário para você, se não for um formulário GETO AJAX é tratado automaticamente pelo jquery-ujs , que lê o token dos
meta
elementos adicionados ao seu cabeçalho porcsrf_meta_tags
(presente no modelo padrão) e o adiciona a qualquer solicitação feita.O uJS também tenta atualizar o token nos formulários em fragmentos em cache desatualizados.
Outras abordagens de prevenção
X-Requested-With
:Origin
cabeçalho: /security/91165/why-is-the-synchronizer-token-pattern-preferred-over-the-origin-header-check-tofonte
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?
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 osession_id
cookie, o servidor sabe:Um hacker pode pensar:
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 aobank.com
domínio, todos os cookies são enviados. Incluindo osession_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:
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 embank.com
... osession_id
cookie será definido e o servidor pensará que o usuário pretendia transferir US $ 1.000.000 para a conta 999999!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 é 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 :
Token de Autenticidade
Quando você
ApplicationController
tem isso:Este:
É compilado para isso:
Em particular, o seguinte é gerado:
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.
fonte
O
Authenticity Token
método is rails 'para impedir ' ataques de falsificação de solicitação entre sites (CSRF ou XSRF) ' .Para simplificar, garante que as solicitações PUT / POST / DELETE (métodos que podem modificar o conteúdo) ao seu aplicativo Web sejam feitas no navegador do cliente e não de terceiros (invasor) que tenham acesso a um cookie criado no lado do cliente.
fonte
desde que
Authenticity Token
é tão importante, e no Rails 3.0+ você pode usarpara criar
qualquer lugar
fonte
XSS
na página de login, não para fins nefastos, mas para criar uma nova sessão com o nome de usuário pré-preenchido. Agora eu sei que posso apenas usarvalue="token_value"
.Cuidado com o mecanismo do token de autenticidade pode resultar em condições de corrida se você tiver várias solicitações simultâneas do mesmo cliente. Nessa situação, seu servidor pode gerar vários tokens de autenticidade quando deve haver apenas um, e o cliente que recebe o token anterior em um formulário falhará na próxima solicitação porque o token do cookie da sessão foi substituído. Há uma redação sobre esse problema e uma solução não totalmente trivial aqui: http://www.paulbutcher.com/2007/05/race-conditions-in-rails-sessions-and-how-to-fix-them/
fonte
Métodos Onde
authenticity_token
é necessárioPor que é necessário
fonte
O que é um authentication_token?
Essa é uma sequência aleatória usada pelo aplicativo rails para garantir que o usuário esteja solicitando ou executando uma ação na página do aplicativo, não em outro aplicativo ou site.
Por que é necessário um authentication_token?
Para proteger seu aplicativo ou site contra falsificação de solicitação entre sites.
Como adicionar um authentication_token a um formulário?
Se você estiver gerando um formulário usando a tag form_for, um authentication_token será adicionado automaticamente, caso contrário você poderá usar
<%= csrf_meta_tag %>
.fonte