Common Misunderstandings in C# and .NET – Failing to Secure Your Secrets Properly

In this section, we will examine how to manage sensitive information within the .NET development environment, with an emphasis on safeguarding secrets utilized during development. These secrets are sensitive data that are essential in the development process.

Imagine a situation where two developers are collaborating on a project, each needing their own unique passwords to access the database. It’s crucial that they avoid sharing these passwords during the development process. Luckily, .NET provides a feature known as “.NET Secrets” to help with this.

Let’s look at an example involving a web application that has a connection string named “Movies,” which is stored in the appsettings.Development.json file. In this case, the connection string includes the UserID but omits the password. The connection string looks like this: “Server=(localdb)\mssqllocaldb;Database=Movie-1;User Id=hieunguyenc;MultipleActiveResultSets=true.”

Although this connection string could have been parameterized, we will concentrate on keeping the password secure for simplicity. To do this, we need to run the “dotnet user-secrets init” command in the Terminal. This command updates the project file by adding a GUID called UserSecretsId. After executing the command, we should check the project file (.csproj) to see the newly created GUID.

Upon inspecting the project file, you will notice that the UserSecretsId has been added to it. This sets the stage for adding secret information such as the database password. To add the secret, we use the “dotnet user-secrets” command and set the relevant key-value pair. For example: dotnet user-secrets set "DbPassword" "pass123". In this case, the key is “DbPassword,” and the password value is “pass123”. You can set other keys and their values, such as the UserID, in the same manner.

Another way to modify values in the secrets file is to right-click on the project in the Solution Explorer and select “Manage User Secrets.” This action saves the secrets to a secure store located in your profile folder, typically at “C:\Users<UserName>\AppData\Roaming\Microsoft\UserSecrets<UserSecretsId>”. Keep in mind that this storage is intended only for development and is not encrypted, so it shouldn’t be used for sharing sensitive information.

To use these secrets, we utilize the ConfigureServices method in the Startup program. Within this method, we can see a SqlConnectionStringBuilder in action. If you’re not using a SQL connection string builder, that’s perfectly fine; the key is to access the secret value through the Configuration extension using the “DbPassword” key. We retrieve the secret value with Configuration[“DbPassword”] and assign it to the Password field in the builder.

You can obtain the generated connection string by calling builder.ConnectionString. To ensure everything is functioning correctly, we can print the database connection stored in the _connection variable.

When you run the application, you’ll see that the password is correctly placed, even though it isn’t defined in the configuration. This illustrates an effective way to manage secrets in your development environment.



For more detailed information about the .NET Secrets extension, you can refer to the Microsoft documentation at the following link: Microsoft documentation on .NET Secrets.

Source: Nguyen Chi Hieu – Technical Manager