I have an ASP.NET Core 2.0 WebAPI application that has Db ConnectionString in appSettings.json.
While in development it has this value:
"DefaultConnection":"Server=localhost;Database=Tyroll;Trusted_Connection=True;MultipleActiveResultSets=true"
and only when we publish it to production we change this with appropriate passwords, by using VS 2017 publish profile.
So SQL server passwords for are not stored on repository and no problem there.
The file appsettings.json is protected by IIS
The question I wonder is should this password be somehow 'hidden' even on IIS?
One reason being additional security, so that SQL credentials are not in plain text in case of breach here.
Another for some authorization scenario where IIS admin should not have directly access to SQL server.
I figure it could be encrypted and the app itself will have key for decrypting it. This would not be 100% secure since in the case of breach on IIS even this key could be reverse engineered from the app, but it would make it more difficult then when it's there in plain text.
So first question is should I be doing this at all?
And second if 1.Q is Yes, what would be the best / recommended way to do it?
Is there some built in tool for this in .NetCore2 or VS2017 or IIS, or some other tool?
Here are some related links:
reddit aspnet_core_appsettingsjson_security_question
stackoverflow is-appsettings-json-protected-by-iis
itprotoday passwords-webconfig
keeping-secrets-in-asp-net-core
I would suggest that you should user Active Directory Integrated security for accessing the database , the App Pool can run under the user account and that particular user account will only have the required access to the database . This safeguards the user credentials in case of an attack since the password is never exposed.
Solution I implemented is making custom encryption of Password in ConnectionString.
But since the App needs to the decrypt it, it is more an Obfuscation.
For encryption I have used AES (using System.Security.Cryptography) and the key is stored: half in connectionString itself and other half hardCoded in the Application.
In addition regex was used to extract Password from ConnectionString and then was replaced with decrypted string of it.
Related
I have currently the following problem, I'm using ASP Identity to handle Authentication, but it is showing me errors because of the XSRF token, one of the solutions is to setup a machinekey setting in web.config. I already have one set, but its from my development computer, so I think I need to generate a new one for my production environment, the problem is that if I change it my current users would not be able to login, I haven't found something yet on how to make this change, how to migrate encrypted passwords into a new machine key.
Machine key is not used for password hashing in Identity (v2 and v3)
I've had some recent difficulty with SQL Server not liking the default AppIdentityUser for logins, so I went ahead and created a custom DB user with write access.
But it made me wonder - is this the best approach?
I was wondering what the best SQL Server login approach would be for Asp.Net Core. I know there's a question similar to this for normal .NET, but you can't encrypt a Core web.config/appsettings.json (well, in a quick and straightforward manner).
Here are the options as I see them:
Connect via SQL Server ID that is stored in appsettings.json.
Pro: Already configured.
Cons: Password in web.config/appsettings.json; have to specifically configure SQL Server ID. Not centrally revokable.
Connect via user NT ID via ASP.NET "AppIdentityUser".
Pro: No passwords in appsettings.json.
Cons: Not centrally revocable. Seems to be restricted to the server name for user.
Connect via Active Directory user.
Pro: Easily revokable.
Cons: Active directory user password in appsettings.json. Could be bad if somebody accidentally reuses that user in another application in the company, and that user gets breached.
Are there other options that I'm missing? Which of these options are used in which situations? Which are more standard? Are there pros and cons that I'm not thinking about?
You should absolutely use a custom SQL Login to connect to the database. Under the hood, the SQL Login could be tied to a local account, service account, network account, etc. It doesn't actually matter.
The real issue you seem to be having here is in not wanting (rightly) to expose login credentials in plain text. I'm not sure why you keep referring to Web.config here, as ASP.NET Core doesn't use that. Instead, there's various configuration providers that can be optionally utilized. By default, ASP.NET Core (at least since 2.0) adds a JSON config provider that looks for appsettings.json and appsettings.{environment}.json in your project, a command-line configuration provider, a user secrets config provider, and finally an environment variable configuration provider.
The last two are the most interesting for your circumstances. In development, you should use user secrets. In production, you should use environment variables. However, neither stores secrets in an encrypted way. The benefit to either approach is that the secrets are not in your project, and therefore also not in your source control. Even though neither is encrypted, it's not as big of a concern as you might think. Getting at the secrets in either would require direct access to the server/development machine. Additionally, user secrets is by default tied to a particular user account, accessible only to that user, and environment variables can be set up the same way. Therefore, someone would need to both gain access to the machine and gain access to the particular account. That's actually a pretty high bar, and if it were to occur, exposing a database password is really the least of your concerns at that point.
Nevertheless, if you want true encryption, you have the option of using Azure KeyVault. KeyVault can be used whether or not your application is actually hosted in Azure, and while it's not free, it's exceedingly cheap.
Finally, you can always create your own config providers or source third-party ones. For example, while the default JSON provider doesn't support encryption, you could potentially write one that does.
Just curious as to best practice for managing db access from an asp.net web application. We were currently putting the username and password in the web.config, but this wasn't good enough internal security (obviously), so I decided to use a windows domain user instead by modifying the web.config to use windows domain, and then adding the user to the app pool identity. This all works fine, but what happens when the domain user's password changes? Does that mean that all the webapps that use this user's identity in app pool will require the password change too? This would be an IT nightmare. Does anyone have suggestions on best approach for allowing webapp to access database without exposing password and without having to update passwords in all webapps if the password changes? Thanks
A better solution would be to set up a separate app pool that is set up with a service account that has full access to the database restart the web app after selecting the new app pool and use integrated security.
Use a very strong ( and lengthy ) password and set the account to password does not expire and user can not change password.
This prevents using clear text in the web.config files.
I would recommend using SQL Mixed-mode Authentication and using a SQL account for your app. The username and password in the web.config and encrypt that section of the config file.
Here is some information about configuration encryption.
http://msdn.microsoft.com/en-us/library/zhhddkxy(v=vs.100).aspx
What is the risk of not using a trusted connection?
For example here is a scenario: I have created a very simple application which only has 4-5 lines of codes which uses an SQL connection with my connection string within web.config, and sends a select command to my database, and display results in an interface.
What are the security weakness here?
Edit:
I know trusted connection is related to authentication, what I wonder is I don't know how can the system be hacked if I don't use it ? (I will use my application at my company's servers and the application is a public application, so every company member can use it, so why do I need a trusted connection if it is a local company application ?)
To look at it the other way around, the main benefit of trusted connections is that you do not have to manage passwords in your application. If your application needs a password to connect to SQL Server, then where do you put the password (or connection string) so that the application user (or other developers, or sysadmins, or external consultants, etc.) cannot read it but you can still change it easily when required?
Passwords in files or the registry can often be read by users because when they run the application it has to retrieve the password, therefore the user needs access. Or a sysadmin or consultant has access to the filesystem where an application config file is. Obfuscating the password with some form of encryption is possible, but then you have to secure and manage the decryption key. Hard-coding the password in the application makes it difficult to change and also makes it highly likely that the password will be visible in the source control system, which is typically a relatively insecure system (in practice, if not by design). You can create a web service that the application gets the password from on startup but then you have to authenticate access to the service somehow.
Using trusted authentication avoids all of this completely by making the operating system responsible for authentication and unless you are a world-class security programmer, the odds are good that Windows provides a more reliable mechanism than you can create yourself.
I will use my application at my company's servers and the application
is a public application, so every company member can use it, so why do
I need a trusted connection if it is a local company application ?
Security risks in non trusted connection lies how you store SQL server passwords and use them in application. if you store passwords in config file or hard code in program, any other developer who has access on your code can view it and on the worst can change database in such a way that may break application or steal sensitive information. it will be a privacy breach as well and your company may be sued for this ( you can't just imagine what can happen).
#Pondlife has also elaborated very well.
AFAIK, the only extra layer of security a trusted connection gives is authentication. If you use a trusted connection then Windows will authenticate your connection in Active Directory.
A quick google yields this link:
What is a Trusted Connection?
I have a web application developed in .net 3.5, and a SQL Server database.
Current auth method is a connection string in web.config, it seems like a good idea to move the authentication details out of plain text.
So, I have two questions:
Trusted Connection - The password policy here is strict, requiring frequent changes. Does this mean i'll have to update the password for the website every time it expires?
Is there another/better option?
As an alternative to trusted connection you can look at this set of articles on how to encrypt your web.config.
In brief, if you invoke from command-line
aspnet_regiis -pe "connectionStrings" -app "/SampleApplication" -prov "RsaProtectedConfigurationProvider"
section connectionStrings in the web.config of application SampleApplication from the default site will be encrypted using RSA.
I think putting the username/password is better simply because I don't want the user that runs my IIS server to have access to lots of databases. I would prefer to have it be focused, to where, for this application there is a user and that user has only access to this database.
You do need to be certain that your web.config file is secure, so you do need security on that.
If you want more security you could just use a dependency injection framework, and inject the compiled class that has the username/password, and just use that connection string. This class could be obfuscated, if you want some semblance of more security.
No, you won't have to keep changing the trusted connection details. You don't store the password there, so password changes won't affect you. (This is if you're using Basic Authentication, getting the users to connect to the SQL box as themselves)
But - if your application pool is running as a particular user, and that user has its password changed, you'll need to update that. You could consider having a user whose password doesn't expire for this.
Trusted connection isn't an option? A frequently changing password shouldn't be a limiting factor in your decision, since it's trusted you don't have to enter a password.
Another alternative is encrypting the connection string.