Introdução
CSRF/XSRF (Cross-Site Request Forgery) é um dos ataques mais conhecidos, existe desde a fundação da Web. Ele ocorre quando uma requisição HTTP é feita entre sites na tentativa de se passar por um usuário legítimo. Quem se utiliza desse tipo de ataque normalmente foca em fazê-lo esperando que usuário alvo esteja autenticado no site onde a requisição fraudulenta será realizada, a fim de se ter mais privilégios e acessos à operações. E a razão de todo o problema está em como os navegadores lidam com os Cookie
Como funciona o CSRF
Para entender o CSRF, é mais fácil imaginarmos um cenário clássico:
- Você loga no site do seu banco usando o seu navegador preferido. A credencial do usuário é valida, um cookie é enviado na resposta da requisição HTTP. A partir desse momento, o navegador tem salvo no disco o cookie que te mantém autenticado.
- Você recebe um e-mail (Engenharia Social) que te convence a clicar em um link que abre um site arbitrário.
- Ao entrar nesse site, no corpo dele, tem um formulário mais ou menos assim:
<form id="meuFormSacana" action="url-do-banco/transferir" method="POST">
<input type="hidden" name="para" value="Kennedy">
<input type="hidden" name="valor" value="R$100">
</form>
Esse formulário no site do atacante emula exatamente como o seu banco faz para realizar uma transferência de dinheiro. Em seguida, em algum momento, esse site arbitrário submete o formulário usando JavaScript:
document.getElementByID("meuFormSacana").submit();
E é daí que vem o nome “Cross-Site Request Forgery”. Foi forjada uma requisição Cross-Site, de um site para outro.
A requisição forjada não é exatamente o problema, mas sim o fato de o seu navegador ter enviado junto com ela aquele cookie de autenticação e o site do seu banco achará que foi você quem solicitou a transferência.
O envio do cookie é feito automaticamente pelo navegador. Quando um cookie é criado, ele possui alguns atributos e um deles é o domain que fala ao navegador do domínio onde esse cookie pode ser transacionado. Uma vez que o site do atacante fez uma requisição ao domínio do seu banco através do seu navegador, o cookie disponível para esse domínio é enviado.
Obviamente esse é um exemplo hipotético e simplista, apenas com o intuito de ilustrar um caso de ataque, ademais, há muitas formas do seu banco mitigar esse tipo de ataque e certamente ele o faz.
Há de ressaltar, ainda, que esse exemplo é apenas uma das formas de ataque CSRF. Outra muito importante e explorada é quando se tem alguma vulnerabilidade (CWE-79) Cross-site Scripting (XSS) onde, por exemplo, o atacante consegue injetar um JavaScript malicioso na página do seu site a partir de um formulário que não rata os dados recebidos, muito menos escapa na hora de imprimir no HTML.
Limitações
- O atacante deve ter como alvo tanto um site que não verifica o campo Referer do cabeçalho HTTP (que é comum) ou uma vítima com um bug no navegador ou plug-in que permite alterar o campo Referer (o que é raro).
- O atacante deve encontrar uma submissão do formulário no local de destino, ou uma URL que tem efeitos colaterias, que faz algo (por exemplo, transferências de dinheiro, ou mudanças de endereço do e-mail ou senha da vítima).
- O atacante deve determinar os valores corretos para todos os formulários ou entradas URL; se qualquer um deles são obrigados a serem os valores de autenticação secreta ou identificação o atacante não pode adivinhar, o ataque irá falhar.
- Oatacante deve atrair a vítima para uma página Web com código malicioso enquanto a vítima está conectada ao site de destino.
Nota-se que o ataque é cego, ou seja, o invasor não pode ver o que o site-alvo envia de volta à vitima, em resposta aos pedidosforjados, a menos que ele explore um (CWE-79) Cross-site Scripting (XSS) ou outro bug do site alvo. Da mesma forma, o atacante só pode ter como alvo algum link ou apresentar qualquer formulário que surge após o pedido inicial forjado, se essas relações subsequentes ou formulários são igualmente previsiveis. (Alvos múltiplos podem ser simulados, incluindo várias imagens em uma página, ou usando JavaScript para introduzir um atraso entre os cliques). Dadas essas limitações, um atacante pode ter dificuldade em encontrar registros das vítimas ou envios de formulários atacáveis. Por outro lado, as tentativas de ataque são fáceis de montar e invisíveis às vítimas, e projetistas de aplicaçõessão menos familiarizados e preparados para ataques CSRF do que para, digamos, ataques de adivinhação de senha dicionarizada (Brute Force Attack).
Prevenção
Os usuários individuai da Web que usam versões não modificadas dos navegadores mais populares podem fazer relativamente pouco para evitar cross-site request forgery. Logout dos sites e evitar o recurso “lembrar-me” podem mitigar o risco de CSRF; não exibir imagens externas ou não clicar em links de spam ou não confiáveis nos e-mais também pode ajudar.
Extensões do navegador, como RequestPolicy (para o Mozzila Firefox) pode evitar o CSRF, proporcionando uma política padrão para negar pedidos de cross-site. No entanto, isso pode interferir significativamente com o funcionmento normal de muitos sites. A extensão CsFire (também para o Firefox) podem mitigar o impacto do CSRF com menos impacto sobre navegação normal, removendo informações de autenticação de solicitações cross-site.
Web sites têm várias contra-medidas para o CSRF disponíveis:
- Exigindo um segredo, específico do token do usuário em todas os formulários de submissoes e o efeito colateral das URLs impedem o CSRF; o site do invador não pode colocar o token direto nas suas alegações
- Exigir que o cliente forneça dados de autenticação na solicitação HTTP mesmo se utilizado para realizar qualquer operação com implicações de seguraça (transfêrencia de dinheiro, etc)
- Limitar o tempo de vida de cookies da sessão
- Verificando o cabeçalho HTTP
Referer
- Assegurando que não há nenhum arquivo
clientacesspolicy.xml
para a concessão de acesso não intencional aos controles Silverlight - Assegurando que não há nenhum arquivo
crossdomain.xml
concedendo acesso não intencional de vídeos em Flash - Verificando que o cabeçalho da socilitação contém um
X-Request-With
. Usado por Ruby on Rails e Django. Essa proteção tem sido comprovada como não segura sob uma combinação de plugins do navegador e redirecionamento, o que pode permitir um invasor forneça cabeçalhos HTTP personalizados em uma solicitação para qualquer site, portanto, permite um pedido forjado. Uma variante desta abordagem é duplicar o envio de cookies para usuários que usam JavaScript. Se um cookie de autenticação é lido usando JavaScript antes que a postagem seja feita, as regras de cross-domain JavaScript mais rigorosas (e mais corretas) serão aplicadas. Se o servidor requer solicitações para conter o valor do cookie de autenticação no corpo de pedidos POST ou a URL perigosa solicita o GET, a solicitação deve ter vindo de um domínio confiável, já que outros domínios são incapazes de ler os cookies do dompinio confiável. Verificando o cabeçalho HTTPReferer
para ver se a solicitação é proveniente de uma página autorizada é comumente usado para dispositivos de rede incorporada, porque não aumenta os requisitos de memória. No entanto, um pedido que omite o cabeçalho Referer mediante a emissão de pedidos de FTP ou URLs HTTPs. Esta rigorosa validaçãoReferer
pode causar problemas com navegadores ou proxies que omitem o cabeçalhoReferer
por razões de privacidade. Além disso, as versões mais antigas do Flash (antes de 9.0.18) permitem que o Flash malicioso gere pedidos GET ou POSTcom cabeçalhos arbitrários de solicitação HTTP usando CRLF Injection. Vulnerabilidades CRLF são semelhantes a injeção em um cliente ue pode ser usado para falsificar a referência de uma solicitação HTTP.
Para evitar falsificação de pedidos de login, os sites podem usar essas contramedidas do CSRF no processo de login, antes mesmo que o usuário esteja logado.
Sites com as necessidades de segurança especialmente rigorosas, como bancos, muitas vezes efetuam logoff dos usuários (por exemplo) depois de 15 minutos de inatividade.
Utilizar o modo de uso específico do HTTP para GET e POST, em solicitações GET nunca terão um efeito permanente, é uma boa prática, mas não é o suficiente para evitar CSRF. Atacantes podem escrever JavaScript ou ActionScript que invisivelmente envia um formulário POST para o domínio de destino. No entanto, filtrando GETs inesperados, impede-se que alguns ataques particulares, tais como ataques de cross-site usando URLs de imagens maliciosas ou endereços de link e de cross0site vazem informações atravpes de elementos <script>
(JavaScript hijacking); mas também evita (não-relacionadas à segurança) problemas agressivos com Web crawlers e Link prefetching.