Vamos entender o CSRF
Oi, pessoal. Tudo bem?
Hoje, resolvi falar sobre essa vulnerabilidade: CSRF (Cross-Site Request Forgery)
Essa vulnerabilidade ocorre quando uma requisição é feita por um usuário e ele não sabe que a executou. Isso ocorre, ao criar uma página falsa de um site e pedir para o usuário clicar, onde os valores dessa página estarão com os valores setados pelo atacante, por exemplo.
<form id="meuFormAlterado" action="url-original/tranferir” method="POST">
<input type="hidden" name="nome_transferir" value="Taylor">
<input type="hidden" name="valor" value="R$10">
</form>
Assim, como vemos no código anterior, o usuário não observa que existe um valor setado no campo "valor", pois o tipo de input é "hidden". Um outro ponto importante de observar é que essa vulnerabilidade ocorre com método POST. Isso ocorre por esse método ser difícil do usuário analisar o corpo da mensagem que está sendo enviada, diferente do método GET que é possível analisar pela própria url.
Eu resolvi abordar esse exemplo, onde coloquei na app vulnerável, pois tenho visto que essa é uma vulnerabilidade que não é tão simples de ser compreendida pelos desenvolvedores.
Então, resolvi criar um exemplo prático em Python e colocarei ao final desse artigo, uma mitigação que serve para qualquer linguagem, como também, colocarei uma mitigação específica para .Net
No código, podemos ver a biblioteca do CSRF para Flask comentada para assim, testarmos a falha.
No nosso código html, possuímos o seguinte código:
Para testarmos a vulnerabilidade, utilizei o Insominia , para simular uma requisição POST, com o usuário logado na aplicação (ou seja, sessão ativa)
Nessa imagem, podemos ver que foi possível transferir as informações nos campos fname e lname.
Agora, se habilitamos o @csrf.exempt , é possível ver outra resposta abaixo:
Ao inspecionar o Navegador, também podemos ver o token sendo gerado de maneira randômica 💜
E o que isso significa?
Ao habilitarmos o CSRF token, não é possível que alguém possa acessar aquela url e enviar um formulário sem ser exatamente aquele usuário.
Assim, a aplicação está validando tanto se o usuário está autenticado na aplicação e agora, se o token do usuário é daquele mesmo usuário. Esse token é randômico e assim, não tem como um atacante colocar essa informação no formulário, igual no primeiro código que coloquei acima 😎
Portanto, para o Python, utilizando o Framework do Flask, só precisamos dessa biblioteca CSRFProtect . Como também, adicionar o CSRF token no frontend da aplicação pois esse token precisa ser passado para o formulário e ser validado ao backend junto ao token de sessão do usuário, conforme expliquei anteriormente.
Já para .Net, temos uma biblioteca muito parecida com que ocorre em Python. Precisamos adicionar no frontend (formulário) e validar no backend.
Backend:
[HttpPost]
[ValidateAntiForgeryToken]
public async EditAdmin(AdminModel account){
// Ações para alteração do Admin
}
Frontend:
<form action=”/” method=”post”>
@Html.AntiForgeryToken()
</form>
Para demais linguagens, caso não hajam uma biblioteca específica no Framework como explicadas anteriormente, devemos seguir o seguinte modelo:
csrfFormToken = request.getParameter(‘csrfToken’);
csrfSessionToken = session.getAttribute(‘csrfToken’);
if (csrfFormToken != null || csrfFormToken.equals(csrfSessionToken)) {
if (isAuthenticated(session)) { // DO }
}
else { // Throw an exception
}
Pois assim, estaremos jogando uma excessão para a aplicação caso o token da sessão do usuário e do formulário não sejam iguais e que a sessão não seja nula.
Assim, manteremos nossa app cada vez mais segura! 💜
Espero que tenham gostado 👩💻✨
Referências: