Protegendo seu site de ataques (CSRF ) com ValidateAntiForgeryToken Asp.Net MVC4 com C#(CSharp)

Autor : Antonio Carlos Ferreira de Azevedo
Postado em : 09/01/2017


Ataque CSRF - (Cross-Site Request Forgery)

Cross-Site Request Forgery (CSRF) é um ataque que força um usuário final a executar ações indesejadas em um aplicativo da Web no qual elas estão atualmente autenticadas. CSRF ataca especificamente as solicitações de mudança de estado, e não o roubo de dados, uma vez que o invasor não tem maneira de ver a resposta ao pedido forjado. Com uma pequena ajuda de engenharia social (como o envio de um link via e-mail ou bate-papo), um invasor pode enganar os usuários de uma aplicação web para executar ações de escolha do atacante. Se a vítima for um usuário normal, um ataque CSRF bem-sucedido pode forçar o usuário a executar solicitações de mudança de estado, como transferir fundos, alterar seu endereço de e-mail e assim por diante. Se a vítima for uma conta administrativa, a CSRF poderá comprometer todo o aplicativo da Web.
Se você utiliza o método [HttpGet] o risco ainda é maior, pois seus dados estão expostos no link do navegador.


@Html.AntiForgeryToken()

Quando utilizamos a instrução @Html.AntiForgeryToken() em nossas páginas será gerado um campo oculto(hidden) em nosso formulário que contém o token CSRF. Este token é enviado ao servidor, que tem de verificar se o pedido tem um token válido. Isso pode ser feito adicionando o atributo [ValidateAntiForgeryToken()] ao método controller.

Segue exemplo de código Html onde invocamos o método para gerar nossa chave (token)

@using (Html.BeginForm("CadastroAluno", "Escola", null, FormMethod.Post, new { Class="form-horizontal" }))
 {
      @Html.AntiForgeryToken()
      // Seus inputs aqui
 }

A instrução @Html.AntiForgeryToken() vai gerar um resultado parecido com o exposto abaixo quando a página for montada em seu navegador.

<input name="__RequestVerificationToken" type="hidden" value="Q1-sCqWrO6auGyIfTZpLZbMzVDwdWjW6lrx3vrCAHj1o1I1jHN6ADGVdzDfd1Vrf1MXN7jgEGPejqps70erZamQg2fNgg1UCG3otc62VH-hkphIUi8KFS2ailHaOBgZm4oK-tmwPRfrjNX-esnqu3s1FPLX5aCVVi4IhiOmsWW41">

Está chave será enviada ao servidor que vai se encarregar de validar quando sua solicitação for executada.

[ValidateAntiForgeryToken]

Agora é preciso informar que a View em nosso Controller deve verificar se nosso token recebido existe e se o mesmo é válido, fazemos isto especificando o atributo [ValidateAntiForgeryToken] antes de declarar nossa View.

Exemplo do uso do atributo

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CadastroAluno(ModAluno aluno)
{
     // Nosso código
}

Com este código, caso nossa View não receba o token ou este não seja válido será gerado um erro.

Habilitando a validação por token em todas as nossa solicitações

Por muitas vezes, no meio da correria do dia a dia, pode acontecer de esquecermos de declarar a chave [ValidateAntiForgeryToken] em alguma de nossas Views deixando assim algo vulnerável a ataques, vamos aprender agora a deixar como defaul a validação habilitada.
Em sua aplicação procure pela pasta App_Start, nela você vai encontrar FilterConfig.cs, abra e adicione a linha como segue abaixo:

filters.Add(new ValidateAntiForgeryTokenAttribute());

Pronto, agora todas as suas solicitações vão conter por default o atributo [ValidateAntiForgeryToken] e não vai mais precisar se preocupar em declarar.

Filtrando somente o método Post

Com o código acima todas as solicitações vão esperar receber o token, caso não queira que seus métodos Get sejam incluídos em sua regra vá até sua pasta Models crie uma classe com o o nome de ValidateAntiForgeryTokenOnPost.cs, copie e cole o código abaixo:

/* 
 * Visite nossa página http://www.codigoexpresso.com.br 
 */
using System.Web.Helpers;
using System.Web.Mvc;

public class ValidateAntiForgeryTokenOnPost : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.HttpMethod != "GET")
        {
            AntiForgery.Validate();
        }
    }
}

Agora va em seu FilterConfig.cs na pasta App_Start e cole o seguinte comando:

filters.Add(new ValidateAntiForgeryTokenOnPost());

Agora somente as solicitações utilizando o método Post terão o atributo [ValidateAntiForgeryToken] declarados por default.

Validação por token em suas solicitações Ajax

Segue abaixo exemplo de função em JavaScript onde geramos nosso token através da Função gettoken() e poderá ser utilizado em suas todas as solicitações:

<script>
    // Gera o token
    function gettoken() {
        var token = $('[name=__RequestVerificationToken]').val();
        console.log(token);
        return token;
    };


    // Exibe os dados do aluno gerando a chave de validação token
    function DisplayAluno(idaluno) {

        $.ajax({
            type: 'POST',
            url: '@Url.Action("DisplayAluno","Home")',
            data: { __RequestVerificationToken: gettoken(), 'idaluno': idaluno },
            dataType: 'html',
            cache: false,
            async: true,
            success: function (data) {
                $('#divDisplayAluno').html(data);
            }
        });

    };
</script>




Comentários