Como evitar mass assignment no asp.net mvc

Para quem não conhece, Mass Assignment é uma vulnerabilidade onde alguém consegue manipular / alterar informações que elas não deveriam ter conhecimento / acesso. Vamos imaginar a seguinte situação: Você possui a seguinte classe:

public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public bool IsAdmin { get; set; }
}

Agora você quer criar uma página onde os seus usuários poderão alterar as suas informações, que no caso seriam os campos Nome e Email. Não acredito que seria interessante deixar uma opção para o usuário decidir se ele quer ser administrador ou não do sistema.

Agora vamos imaginar que você está utilizando algum ORM, como o Entity Framework por exemplo. Caso você exponha a classe usuário em sua view, e espere em seu controller um usuário, persistindo-o da maneira que ele foi enviado, você está permitindo que qualquer usuário possa manipular qualquer informação persistida na tabela usuário (ou equivalente). Como isso funciona?

Quando utilizamos o binding do asp.net mvc, ele segue algumas convenções para conseguir realizar o parse das informações enviadas em um objeto. O html para alterar o usuário no caso, ficaria com algo parecido com:

<input type="text" name="Name" />;
<input type="text" name="Email" />;

Quando você submeter este formulário, caso você esteja esperando um User no controller, o asp.net mvc saberá que o input com name “Email” deverá ser preenchido na propriedade com o nome equivalente. Caso você confie neste formulário, e persista as informações da maneira como recebeu, você pode estar dando mais controle do que gostaria ao usuário, no caso, estar recebendo a informação IsAdmin como verdadeiro, mesmo que esta opção não estava inicialmente no formulário. Existem diversas formas de fazer isso, afinal, isso é apenas uma requisição http enviando algumas informações para a sua aplicação. Você pode brincar com o Fiddler caso queira, e ver como uma comunicação pode ser frágil quando não tomamos as medidas certas.

Existem algumas maneiras de evitar uma situação dessas, como criando uma Whitelist ou Blacklist com os parâmetros que você receberá, mas acredito que a melhor alternativa sempre será utilizar view models que representem a sua view, no lugar de expor o seu domínio, e neste caso, suas tabelas do banco em uma página html. Existem diversos outros problemas ao acoplar as suas views com os seu domínio que não abordarei neste post.

Bom, por hoje é isso. Muitas vezes, através de uma pequena falha em como implementamos os nossos sistemas, podemos estar correndo sérios riscos.

Abraço 😉

ps: Lembrando que essas questões não valem apenas para o asp.net mvc. E caso você ache que isso é algo que qualquer um pensaria, saiba que até o próprio github já sofreu com esta vulnerabilidade.

Anúncios