How To Keep SECRET Strings REALLY SECRET in ASP.NET Core?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
security is a critical topic when it comes to application development and I'm glad that most Engineers take it really seriously we spend a lot of time researching investigating looking through oasps cheat sheets thinking about cryptography encryption at rest and other very complex topics but then we do this which ultimately translates into something like this yes having secret strings like a database connection string in our source control system and that's wrong in so many ways now what can we do about that stand by as in this video I'll show you how we can easily keep secret strings really Secret in asp.net core applications hello and welcome to the code wrinkles channel for this brand new video so how do we keep secret strings really Secret in asp.net core there are at least two ways to achieve this and everything boils down in the end to asp.net core configuration yes that's topic that everybody knows it exists but few people put in the time to actually understand it and leverage it into every day's work so when an asp.net core application is executed it goes through different stages of configuration until we can use it one of these stages is reading configuration information which is usually stored in form of key and value Pairs and I know we are tempted to think that configuration information goes into the app settings.json file but in reality we have different configuration sources like environment variables like user Secrets like command line arguments like if your app configurations and many more let me show you how this looks like in practice we are here in running.net 7 minimal API and I have placed a breakpoint so that we can pick into what this Builder actually contains and we see that one of the properties that it contains is this configuration and that's basically the place where we can look into what exact configuration sources the application is using to provide us a lot of information that we can then reuse in our application and here we have these providers providers are just instances of or or objects that are configured to read configuration in form of key value pairs from different sources and as I mentioned earlier we can have different sources for configuration we have this in memory configuration provider but we have also these environment variables configuration provider we see that we actually have two providers one that looks into values or into keys that start with asp.net core one that looks into keys that start with.net and then we have also the Json files as configurations provider like we have this app settings.development and app settings.json in fact if we look into this app settings.json we see that we have all the configurations that we have placed in the app settings suggestion file which is the standard or default configuration that comes with an asp.net core minimal API template and we see here the log level a lot of information regarding logging and then we have these connection strings and the default which is the connection string that I have in my app settings.json file which is bad so we will try to solve this problem now the idea is that as we can see here we can provide actually the connection string or secret strings not only in app settings.json but we can provide those type of configuration or this type of information in other sources where asp.net core can look in by default and get that configuration and of course we can also create our custom configuration providers but that's not something that we'll tackle in this video now let me walk you through some different places where we could place our configuration and also look how this would work but before we solve our problem with the secret string I want to show you how this conceptually works because there's really room for for a lot of problems here if you don't understand how configuration works the right way so let me add the configuration first to this absentice.json file which is what we would usually do in applications we have a key which is called code wrinkles and then we have this type of value which is called wrinkles in app settings.json and this is nothing new compared to what we are usually accustomed to do now let's go to the next part and understand that okay we said that we can also set information in environment variables now environment variables are a little bit trickier because they are set usually at operating system level and you might use partial if error on Windows or bash to set this environment variables or if you're using.net core we have this launch settings.json file which allows us to set the environment variables and in fact if we look into this we see that it already has an environment variable which is this asp.net core environment which is set to develop if you want to easily configure our environment variables in our dotnet core application we can come simply here in the launch settings.json file and in this case I'll just change this from app settings.json to this launch settings.json file and here we could place our environment variables I said so it means that what we could do is also we could theoretically place our connection string but we will come to this just a little bit later now there is a third place where we could place easily our configuration and this is give it as part of the command line arguments that we pass through the application right when the application is executed we'll also want to set our command line arguments in this large settings.json file because we want to have them available when we run this application in the debug mode but if you're running or starting the.net core application from the command line then you can provide those arguments directly as command line arguments so what we'll do here is We'll add these command line arguments and here we add this in this form of code wrinkles this is the key and this is the value now we are set with that and I want to show you this in action because here there is really a big caveat so in order to do that let me go back here to our application or to our program.cs and let me add this line of code Builder configuration get Section code wrinkles and you might notice that what I have done I have used the same key like in the app settings.json file and I have used the same key here in the environment variables and I have used the same key here in our command line argument so let me run the application and let's see what we have in this variable so let's debug that so that it starts at or that it stops at this breakpoint so we'll be able to take a sneak peek into what we'll have in this code wrinkles variable which might be very insightful for us and to understand better how configuration Works in asp.net core so I guess we are already here and yeah if we hover our Mouse here we see that in Discord wrinkles we have this code wrinkles from command line so what we learn from this is that even if we have specified the coding because key in the app settings.json file we have specified it as environment variable and then we have specified as commonly an argument the thing is that when we arrived here at this line basically it took the configuration that we had in the command line and this is important because the order in which you specify the keys measures just like or similar to what we are accustomed to have in middleware we need to be careful about that if we have or if we reduce the same name for the key in different configuration sources and the best way to think about this in my opinion is that we can easily remember the order in which this type of configuration is read by the providers because the last one that is read by the configuration provider that one basically overrides everything that was previously defined and will be used and the Order of configuration or how configuration is added is first the app settings to Json then it reads the configuration from environment variables like this one and then it reads the configuration from the command line argument so this means that when the application started it first read the configuration from here and it was this value but then it read the configuration from here and then it had this value and last but not least it actually read the configuration from the commonlin arguments and it had a different values so basically all the others were overridden and we can simply prove that if we for instance remove this and we run the same application again the output should be different and I would expect it in that case we have we should have this value called wrinkles in environment variables because in this case this is the last one that is red and it should be the one that overrides everything so if we place our cursor here or we can see it even here code wrinkles and we see code wrinkles from environment variables I guess you already imagine if we go to this large settings to Json and we remove this from here then what we'll end up having is of course in this code request variable we will have the value from the app settings.json file which will would be these called wrinkles in app settings.json now let me remove this because we don't need that anymore and let's go back to our original topics how do we keep our secret strings really secret so we have this connection string in our app settings to Json and this is what will take as an example and we want to solve this problem so we want to use this connection string and set it somewhere where it's actually not part of the source control now if we cannot set it in the app settings.json file the next possible thing to do is well we would set it as an environment variable however here we need to be a little bit careful because if we go here and set the environment variable here in this large settings.json file the problem is that this file is also part of the source control and it actually should be as per the official specification or notification or information by Microsoft launch settings.json or yes launch settings.json should be part or could be part of source control so this means that we can cannot even set our connection string here because this it will still end up being in Source control and we have already said that this is a total no-go now of course if you think about deploying this application to production then the discussion is a little bit different because theoretically then you could set the connection string in an environment variables because in that case probably you would have a CI CD and you would be able to set the environment variable via Powershell if you're running on Windows or via bash if you're running on Linux so that would be okay from the perspective of deploying the application however that still doesn't really solve the problem for us as developers where do we place our connection string so that we can actually debug the application and work with that and to do that I want to introduce you to a totally different configuration source which is the user secrets to work with user secrets we need to go to the terminal and here for instance we are already in the folder where we have our API project and we can run here.net user secrets and here we have access to a bunch of different functionalities on user secrets and one of them is list this will of course list all the user secrets that you have right now configured for this project of course we don't have any user secret configured yet but that will change very shortly the idea is that user secrets are something that's really helpful for you as developers to really place your secret strings so that nobody sees them and that they are not part of source control and when you debug the application when you run it locally.net core has a configuration provider that will look into this and bind all the key values that it finds here and it will add them to your application configuration so this means that what we can do here is we can come and say dotnet user Secrets set and then we can set our connection string and for instance I want to be able when I am here in this program and have designed it Builder configuration get connection strings and then I provide a default I want this line of code to still work because I don't want to have additional code that I will have to write to actually handle this so what I will end up doing is I will simply name my key in this form so it would be connection string and then Dev so I'm using Dev in this case not default and I will change that because I want them to be different to Showcase that it actually works the idea is that all the configuration that we provide even in Json format when we have Nest adjacent objects when the configuration provider reads that configuration it gets flattened to something like that so what we have here in app settings.json like connection string and default will be flattened in something like connection string and then default and that's the reason why we have used the same convention but already provided this information in a flat and format so connection strings dot Dev now we have done this we can just say press enter and then these secrets will be successfully added and in fact it shows us that it has added these secrets to our folder and now what we can do here is yeah we can get simply rid of the connection strings that we have in our app settings the Json file can come back to our program now the only thing that we need to change because we have used a different naming here to Showcase that it really works and it doesn't read the configuration from the other part so if we run the application right now in debug mode we will see that we should have in the Cs the correct connection string and now this secret string is or should be really secret for our application so if we look into that we see that in the Cs we have indeed the connection string that we have provided before we wrap this up I really want to spend just a few seconds on discussing how this would actually look like in a real production like scenario or production like application the main thing is or the thing that we need to be careful is once again we shouldn't have secret strings in our app settings.json file this includes but is not limited to connection string passwords or other things that are really be sensitive and that shouldn't be visible at all now there are two challenges or there are two aspects on this the first one is okay we don't or we we wouldn't have this connection string in app settings to Json so what do we do as developers so that we can still use a connection string and debug and run our application locally when we develop so that's the first concern and we have tackled this first concern in this video and we'll show the best way to actually do that is to use this user secrets and to add your connection string to your users secrets on that project and when you are developing locally everything will work just fine now the second facet to this part is that okay how do we handle this when we want to deploy this application to production because if we don't have an app settings.json or a connection string in the app settings or Json file how will it be able to run once the application is deployed and here we actually things should be fairly easy as well because we have different options depending on really what set ICD tools are we using what what environment or infrastructure we use to host our application for instance most of the CI tools for instance like Jenkins or team City like even Azure devops are able to provide on the Fly variables or value for variables for certain configurations so that's something that could be set up at a devops level then if you're running for instance the application in Azure either provide you also a way in an Azure web app to configure environment variables or to configure variables for that specific application and net core will by the way by default also read Azure app configuration if present so there are really a lot of different ways to achieve this and it's not really complicated however once again the most important thing is to keep secret strings really secret to keep them on your local development environment and then devops should take care about how that should be placed or how that should be deployed so that the application knows exactly what connection string to use but if you happen to also do the devops part for the project that you are working in I have already mentioned also some ways in which you can think about how to use connection strings when you want to deploy this application this being said thank you very much for watching if you have enjoyed this video don't forget to hit the thumbs up button that's really important it helps a lot of other people that might be interested in this topic to discover this video early easier and if you aren't subscribed already please subscribe to this channel also hit the notification Bell so that you are notified whenever we have new content here on the code wrinkles Channel and if you have any question if you want to get in touch with me if you want to get discussion going and discuss anything don't be shy and head over to the comment section and leave a comment and I would be more than happy to get in touch with you and to respond to your comment this being said once again thank you very much for watching and until the next time I wish you the very best
Info
Channel: Codewrinkles
Views: 6,861
Rating: undefined out of 5
Keywords: asp.net core, asp.net core tutorial, asp.net core web api, asp.net core training, asp.net core configuration, asp.net core configuration appsettings.json, asp.net core startup, asp.net core secrets, asp.net core secrets manager, asp.net core secrets.json, asp.net core web api tutorial, asp.net core mvc, asp.net core web api tutorial for beginners, restful web api tutorial asp.net core, .net core
Id: 5TxnLU-SXVg
Channel Id: undefined
Length: 16min 31sec (991 seconds)
Published: Sun Jan 29 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.