Segurança em projetos .NET com User Secrets



...

Fala dev, tranquilo? Comigo está tudo bem, e para terminar o mês venho trazendo mais um artigo fugindo um pouco da série A Fábrica de Arquitetos.

O artigo de hoje é bem rápido, porém é um recurso muito eficiente do .NET a quesito de segurança que muitas pessoas não conhecem, eu estou falando do User Secrets.

 

 

O que é?

 

Imagine que você está trabalhando numa aplicação onde a string de conexão com o banco de dados fica guardado no arquivo appsettings.json, um cenário muito comum no dia a dia de um desenvolvedor .NET.

E quando isso se torna um problema? Bom essa abordagem tem alguns problemas quando a gente trata dados sensíveis, vamos lá, seu banco de dados de produção certamente será diferente do seu banco de dados de desenvolvimento, e em algum momento por acidente você sobe a aplicação para produção com a string de conexão errada e advinha? Bug em produção!

Ok, mas como o User Secrets pode te ajudar com isso? Ele guarda segredos (dados sensíveis) da aplicação em variáveis de ambiente, ou seja, você pode desenvolver tranquilamente pois sua string de conexão e dados sensíveis vão estar no ambiente que você criou.

Outro problema que pode ser resolvido com ele é a questão de dados sensíveis estarem expostos para quem tiver acesso aos arquivos da aplicação no servidor.

Quando você realiza o build da sua aplicação .NET pode perceber que ele gera as .dlls dos projetos e mantém o appsettings.json, então caso alguém com acesso ao servidor queira saber algum dado sensível é só abrir esse arquivo, coisa que com o user secrets é mais complicado e abstraído.

Bom, com isso da para entender a importância de manter dados sensíveis protegidos, mas a pergunta que fica é, devo descartar o appsettings.json e colocar tudo no user secrets? NÃO, como dito anteriormente a finalidade dele é armazenar SOMENTE DADOS SENSÍVEIS, como senhas, tokens, strings de conexão. Dados de configuração NÃO SENSÍVEIS podem e devem ser mantidos no appsettings.json.

 

 

Let’s Code!

 

Bom para a demonstração eu vou criar uma API supersimples, onde eu vou armazenar no user secrets uma chave de criptografia.

Essa API vai ter 2 rotas, Encrypt e Decrypt, onde irei usar a chave armazenada no user secrets para poder realizar as ações de criptografar e decriptar.

Sem muito segredo, criei um projeto Web API em .NET 5 e adicionei o CryptoController com o seguinte código.

 

Perceba que para os métodos de Encrypt e Decrypt ele utiliza IRijndaelCryptography que é uma interface da minha biblioteca EscNet que eu criei para poder me auxiliar em tarefas cotidianas como a de criptografia, você pode saber mais sobre ela no link abaixo.

https://github.com/Eschechola/EscNet

 

Bom, como recebemos a instância de uma classe que implementa IRijndaelCryptography via injeção de dependência, precisamos configurar essa DI.

Para isso vamos no Startup.cs e adicionamos a seguinte linha no método ConfigureServices.

services.AddRijndaelCryptography(Configuration["Cryptography:Key"]);

 

Aí que entra a mágica, geralmente um algoritmo de criptografia pede uma chave de criptografia e como minha biblioteca EscNet realizar criptografia não é diferente.

Perceba que como parâmetro eu passo o seguinte valor. 

Configuration["Cryptography:Key"];

 

Comumente você veria a chave de criptografia armazenada no appsettings.json, mas aqui iremos começar a mágica do User Secrets!

Para começar a usar o User Secrets você deve inicializa – lo na aplicação, para isso o .NET CLI irá nos auxiliar.

Abra o terminal na raiz do seu projeto (onde fica o .sln), e digite o seguinte comando para inicializar o User Secrets.

dotnet user-secrets init --project .\\MyEncrypt\\MyEncrypt.csproj

 

OBS: Onde tiver MyEncrypt, você substitui pelo nome do seu projeto criado!

 

Show, ele irá te mostrar uma mensagem falando que foi criado e te passando uma chave indicando o projeto que irá usar aqueles segredos.

Se você abrir o arquivo .csproj do projeto no qual foi inicializado irá perceber a mesma chave lá (linha 5).

 

Perfeito, agora é só a gente adicionar a nossa key de criptografia utilizando o seguinte comando.

dotnet user-secrets set "Cryptography:Key" "x5qWaAZU3jqSY6WV" --project .\\MyEncrypt\\MyEncrypt.csproj

 

Esse comando recebe primeiramente 2 parâmetros, a chave e o valor, a chave eu deixei igual está na nossa Startup.cs e o valor eu gerei uma cadeia de caracteres aleatória para poder realizar o teste.

Para poder listar as chaves do projeto basta usar o comando abaixo.

dotnet user-secrets list --project .\\MyEncrypt\\MyEncrypt.csproj

 

Além desses comandos o user secrets tem mais 2 comandos, o clear e o remove.

O remove retira apenas UM SEGREDO da aplicação.

dotnet user-secrets remove "Cryptography:Key" --project .\\MyEncrypt\\MyEncrypt.csproj

 

E o clear limpa todos os segredos da aplicação, então tome cuidado, sua sintaxe está abaixo.

dotnet user-secrets clear --project .\\MyEncrypt\\MyEncrypt.csproj

 

Bom agora caso seja necessário realizar o deploy da nossa aplicação não terá chance de afetar os dados sensíveis, pois em produção terá seu próprio repositório de segredos!

Por fim, deve ter ficado uma pequena dúvida de ONDE OS SEGREDOS SÃO ARMAZENADOS?

Relaxa, eles são armazenados em um .json, mas ele é protegido pela conta de usuário, localizado nos endereços abaixo.

 

Windows

%APPDATA%\\Microsoft\\UserSecrets\\\\secrets.json

Linux

~/.microsoft/usersecrets//secrets.json

OBS: Substitua user_secrets_id pelo id gerado quando você iniciou o repositório de segredos (você consegue encontrar ele no .csproj)

 

 

Conclusão

 

Hoje vimos um recurso bem bacana disponível no .NET Core que é a utilização de segredos da aplicação! Com ela sua aplicação fica muito mais segura e evita erros por falta de atenção em ambiente de produção! 

Espero que tenha ficado claro e objetivo o uso desse recurso e que a partir de hoje você possa desenvolver mais tranquilo e sem medo mudar algo em produção por falta de atenção!

Agradeço a atenção e bons estudos!!!!!

Caso precise entrar em contato, me mande uma mensagem aqui.

Baixe o projeto clicando aqui.