Evitando ataques CSRF em aplicações ASP.NET Core
#ASP.NET Core , #Segurança , #CSRF
Olá, você quer deixar suas aplicações .Net Core e MVC mais seguras e previnir contra ataques CSRF ? Vamos descobrir juntos neste post como podemos proteger nossas aplicações contra esta vulnerabilidade, com testes práticos e visíveis.
Antes de mais nada: O CSRF ou XSRF (do inglês Cross-site Request Forgery - Falsificação de solicitação entre sites) é um tipo de ataque malicioso a um website/webapp no qual comandos não autorizados (como alteração de senha, usuarios, registros) são enviados para o servidor usando o browser em que o website/webapp confia.
Gravidade
De acordo com o Departamento Americano de Segurança Nacional o CSRF é a vulnerabilidade mais perigosa classificada em 909° nos bugs de software mais perigosos já encontrados, tornando esta vulnerabilidade mais perigosa do que a maioria dos buffer overflows, para mais detalhes sobre este tipo de ataque, veja aqui
Usar certificado HTTPS não impede este tipo de ataque!
Caso prático para entender
Ok, vamos para um caso bem prático para você entender o problema.
Quando o usuário efetua login em nosso sistema, o browser armazena os cookies de autenticação, então o ataque usa este cookie como a confiança que sistema precisa para executar comandos. E deixar o cookie com expiração rápida não é a melhor estratégia.
Então imagina que o seu usuário recebeu um email assim:
😍
Parabéns! você ganhou um prêmio incrível!
Clique aqui para retirar seu prêmio…
😈 Tá bom , Tá bom, eu sei que forçei a barra, (mas tem gente que clica einh…)
Mas imagine um email com o contexto da empresa
Não consegui abrir o pedido, pode verificar para mim ?
abrir pedido
Se este usuário estiver logado do sistema, e se não estiver preparado para este ataque, o código abaixo será executado!
<form method="post" action="http://webapp.com/users/edit">
<input type="hidden" name="Email" value="admin@admin.com" />
<input type="hidden" name="Senha" value="NovaSenha" />
<input type="submit" value="abrir pedido"/>
</form>
Qual código ? o sistema vai alterar a senha do usuário admin@amdin.com para a nova senha.
A Resolução
Se você usa o ASP.NET Core, ou ASP.NET MVC a solução é muito simples, basta você adicionar a modificador [ValidateAntiForgeryToken] na assinatura do seu método.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id)
{
/// seu codigo
return View();
}
E no seu fomulário
<form method="post" action="Edit">
@Html.AntiForgeryToken()
</form>
Se usar o aps.net Core 2.0 ou superior o FormTagHelper injeta antiforgery tokens em formulários HTML elementos de formulário HTML. Se você quiser desabilitar pode usar o comnado asp-antiforgery=“false” no corpo do formulário.
Em cada um dos casos anteriores, o ASP.NET Core adiciona um campo de formulário oculto semelhante à:
<form asp-action="Edit" method="post" >
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
</form>
Você pode adicionar o modificador [ValidateAntiForgeryToken] a nível de controller, assim todos os métodos abaixo herdarão, não se preocupe métodos GET não usarão este modificador.
[ValidateAntiForgeryToken]
public class HomeController : Controller
{
...metodos
}
Se usa ASP.NET Core, é possível alterar o arquivo Startup.cs e deixar a validação de forma global, prevenindo assim que desenvolvedores esqueçam de usar este atributo.
public void ConfigureServices
{
....
services.AddMvc(options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
}
Você pode usar o modificador [IgnoreAntiforgeryToken] para eliminar a necessidade de um token de antiforgery para uma determinada action (ou controller).
Dica EXTRA!!!!
Ai você me pergunta ? E aquele action, que é um arquivo javascript que chama passando como parametro um JSON ? como faremos ?
O ASP.NET Core nos fornece um método IAntiforgery que tem uma API para poder usar este recurso, então em nosso CSHMTL, usaremos assim:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
E no HTML
<input type="hidden" id="RequestVerificationToken"
name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">
Então em nosso javascript, podemos usar assim:
var token = document.GetElementById("RequestVerificationToken").value;
$.ajax({
type: "POST",
headers:
{
"RequestVerificationToken": token
},
url: { url },
data: { parametros }
...
},
dataType: "json"
});
Resumindo
Proteger nosso sistema contra ataques CSRF é muito importante, mas não a única solução, existem muitos outros ataques que devemos nos preocupar.
É isso, até a próxima semana… :)
Note...
Hy, I'm José Luiz and my commitment is to no bullshit post, no sponsored posts, no ads, and no paywalls.
If you enjoy my content, please consider supporting what I do.