ASP.Net MVC – Cuidado com links de exclusão “Delete” – Pode ser uma falha de segurança

ASP.Net MVC – Ao expor informações de um banco de dados, cuidado com o link do tipo “Delete”, siga essa dica para evitar uma falha de segurança em seu site.

Vamos supor que em nosso site ASP.Net MVC possuímos uma controller “FuncionarioController”, essa controller é responsável pelos métodos de CRUD da sua entidade Funcionario relacionada ao seu banco de dados.

Como o seu ActionResult de exclusão deveria estar escrito? Vamos observar este exemplo:

// GET: /Funcionario/Delete/5

public ActionResult Delete(int id = 0)
{
   Funcionario funcionario = db.Funcionario.Find(id);

   if (funcionario == null)
   {
      return HttpNotFound();
   }

   db.Funcionario.Remove(funcionario);
   db.SaveChanges();

   return RedirectToAction("Index");
}

Algo de estranho?
Teoricamente está tudo certo, o código está validando se o ID existe mesmo e caso não exista o usuário será redirecionando para uma página de erro, assim evitando em exibir mensagens de erro do banco de dados.

Mas nesse código habita uma grande falha de segurança, o ActionResult Delete é um método Get, ou seja, pode ser chamado diretamente de uma URL. O que aconteceria se alguém mal intencionado digitasse no browser a seguinte URL:

www.meusite.com.br/Funcionario/Delete/1

Provavelmente o registro de funcionário com o ID = 1 seria excluído certo?
“Ah, mas minha aplicação requer login e senha para esse tipo de ação.”

Isso não evita de receber um ataque, imagine que um usuário mal intencionado deseja deletar um registro e envia um e-mail para um usuário desse sistema com uma imagem “para parecer inofensivo” e nessa imagem contenha um link para a URL que citamos acima. Se o usuário que recebeu o e-mail e clicou estiver conectado (logado) no sistema naquele momento já seria o suficiente para concretizar a exploração dessa falha.

DICA

Nunca escreva seus métodos Get de exclusão realizando a exclusão direta da base.
A dica completa seria:
Nunca escreva nenhum método Get realizando alteração de informações do sistema.

Como resolver?

Vamos observar uma maneira indicada para evitar a falha citada:

    // GET: /Funcionario/Delete/5

    public ActionResult Delete(int id = 0)
    {
        Funcionario funcionario = db.Funcionario.Find(id);

        if (funcionario == null)
        {
            return HttpNotFound();
        }
        return View(funcionario);
    }

    // POST: /Funcionario/Delete/5

    [HttpPost, ActionName("Delete")]
    public ActionResult DeleteConfirmed(int id)
    {
        Funcionario funcionario = db.Funcionario.Find(id);
        db.Funcionario.Remove(funcionario);
        db.SaveChanges();

        return RedirectToAction("Index");
    }

Repare que existem dois métodos ActionResult para exclusão, o método Get Delete não realiza a exclusão do registro, apenas verifica se ele existe e redireciona o usuário para uma View de visualização e confirmação de exclusão:

ASP.Net MVC Exclusão

Ao realizar a confirmação dos dados e clicar em excluir a página será submetida via Post para o método DeleteConfirmed, que é responsável pela exclusão da base de dados.

Repare no código que um método chama-se Delete (Get) e o outro DeleteConfirmed (Post), repare também que existe um atributo ActionName(“Delete”) decorando o método DeleteConfirmed, isso significa que ele pode ser chamado como Delete, isso é necessário, pois o CLR (common language runtime) do .Net requer que haja apenas um método com a mesma assinatura, como os dois métodos recebem o mesmo tipo de parâmetro não seria possível possuírem o mesmo nome.

Utilizando o atributo ActionName(“Delete”)  faz que o roteamento do site aceite o método DeleteConfirmed como Delete quando uma URL que inclua o /Delete/ for acionada via Post.

Resumo

Essa técnica evita que de forma indesejável um registro seja manipulado e por mais que haja sucesso na tentativa do usuário mal intencionado o site resultará em uma página de confirmação, logo o usuário logado poderá intervir a essa tentativa de burlar o sistema.

Todas as controllers criadas automaticamente em projetos no Visual Studio, seja na criação do projeto ou via scaffolding já preveem essa técnica, caso você esteja criando suas controllers manualmente, lembre-se dessa dica 😉

Referência

Gostou do artigo, teve alguma dúvida? Deixe sua mensagem nos comentários abaixo.

4 pensou em “ASP.Net MVC – Cuidado com links de exclusão “Delete” – Pode ser uma falha de segurança

  1. Boa noite Eduardo,

    Caso eu não queira fazer a confirmação – ou se já tenho feita ela no navegador por exemplo – deixando a action de remoção em POST já não resolveria?

    • Se você criar um post para deletar precisará de um form para isso, mas ok irá funcionar, só preocupe-se em ativar o AntiForgeryToken e verificar se não existe caminhos para burlar e criar um ataque malicioso.

      Abs!

  2. Amigo estou com um problema, estou com alguns dados de produto relacionado a tabela itens pedidos no banco e não consigo fazer a exclusão.
    Qual seria metodo que posso fazer para excluir esse produto?

Os comentários estão fechados.