Estou tentando entender todo o problema com o CSRF e maneiras apropriadas de evitá-lo. (Recursos que li, compreendi e concordo com: Folha de dicas sobre prevenção de RSC do OWASP , Perguntas sobre CSRF .)
Pelo que entendi, a vulnerabilidade em torno do CSRF é introduzida pela suposição de que (do ponto de vista do servidor da web) um cookie de sessão válido em uma solicitação HTTP recebida reflete os desejos de um usuário autenticado. Mas todos os cookies para o domínio de origem são magicamente anexados à solicitação pelo navegador; portanto, na verdade, todo o servidor pode inferir da presença de um cookie de sessão válido em uma solicitação: a solicitação vem de um navegador que possui uma sessão autenticada; não pode mais assumir nada sobre o códigoexecutando nesse navegador ou se realmente reflete os desejos do usuário. A maneira de evitar isso é incluir informações adicionais de autenticação (o "token CSRF") na solicitação, realizada por alguns outros meios que não o tratamento automático de cookies do navegador. Em termos gerais, o cookie da sessão autentica o usuário / navegador e o token CSRF autentica o código em execução no navegador.
Portanto, se você estiver usando um cookie de sessão para autenticar usuários do seu aplicativo da Web, também deverá adicionar um token CSRF a cada resposta e exigir um token CSRF correspondente em cada solicitação (mutante). O token CSRF faz uma viagem de ida e volta do servidor para o navegador, provando ao servidor que a página que faz a solicitação é aprovada por (gerado por, mesmo) por esse servidor.
Na minha pergunta, que é sobre o método de transporte específico usado para esse token CSRF nessa viagem de ida e volta.
Parece comum (por exemplo, no AngularJS , Django , Rails ) enviar o token CSRF do servidor para o cliente como um cookie (ou seja, no cabeçalho Set-Cookie) e, em seguida, fazer com que o Javascript no cliente o retire e o anexe. como um cabeçalho XSRF-TOKEN separado para enviar de volta ao servidor.
(Um método alternativo é o recomendado por exemplo , Express , em que o token CSRF gerado pelo servidor é incluído no corpo da resposta por meio da expansão do modelo no servidor, anexado diretamente ao código / marcação que o fornecerá de volta ao servidor, por exemplo como uma entrada de formulário oculta. Esse exemplo é uma maneira mais isométrica de fazer as coisas na Web 1.0, mas generalizaria bem para um cliente mais pesado em JS.)
Por que é tão comum usar o Set-Cookie como o transporte a jusante do token CSRF / por que essa é uma boa idéia? Imagino que os autores de todas essas estruturas considerassem suas opções com cuidado e não entendessem isso errado. Mas, à primeira vista, o uso de cookies para contornar o que é essencialmente uma limitação de design em cookies parece estúpido. De fato, se você usasse cookies como transporte de ida e volta (Set-Cookie: cabeçalho a jusante para o servidor informar ao navegador o token CSRF e Cookie: cabeçalho a montante para o navegador retorná-lo ao servidor), você reintroduziria a vulnerabilidade está tentando consertar.
Percebo que as estruturas acima não usam cookies para toda a ida e volta para o token CSRF; eles usam Set-Cookie a jusante, depois outra coisa (por exemplo, um cabeçalho X-CSRF-Token) a montante, e isso fecha a vulnerabilidade. Mas mesmo o uso de Set-Cookie como transporte a jusante é potencialmente enganador e perigoso; o navegador agora anexará o token CSRF a cada solicitação, incluindo solicitações XSRF maliciosas genuínas; na melhor das hipóteses, torna a solicitação maior do que precisa e, na pior das hipóteses, algum código de servidor bem-intencionado, porém mal orientado, pode realmente tentar usá-lo, o que seria muito ruim. Além disso, como o destinatário real do token CSRF é o Javascript do cliente, isso significa que esse cookie não pode ser protegido apenas com http.