My app stores db connection-strings in an xml config file that is stored under source-control ( svn ).
When deployed in prod, my app needs to retrieve the encrypted strings and decrypt them.
The ability to perform ad-hoc encryption should be limited to the prod operations group -- nobody else should know the raw prod db connection-strings. Only the encrypted prod db connection-strings are checked-in to source-control
The app's ability to decrypt the strings be limited to its deployment in prod. ( In dev/qa , the config file contains connection strings to non-prod dbs , and these are not encrypted. )
I am wondering if a public/private key certs based mechanism could be adapted for this purpose ?
Or what is a minimalist design ?
Are libs/tools available to this end ?
For Asp.Net applications, reg_iis can encrypt portions of the web.config file for you.
aspnet_regiis -pef MySecrets .
http://odetocode.com/blogs/scott/archive/2006/01/08/encrypting-custom-configuration-sections.aspx
There's a good article on Code Project that outlines how to use that same mechanism for other types of .NET applications:
ASP.NET offers the possibility to encrypt sections in the web.config automatically. It seems it is not possible for WinForm applications to do that for the app.config. And this is true for a part: WinForms does not offer tools to configure it. But it can be done. It is all .NET. Isn't it? So how do we do it?
http://www.codeproject.com/Articles/18209/Encrypting-the-app-config-File-for-Windows-Forms-A
Related
I remember a while ago there was some microsoft utility where you could encrypt sensitive values in an app.config file for a c# Console application. Does anyone know if there is a way to encrypt sensitive values in a dtsconfig file? Obviously the default dtexec.exe would have to recognize encryption in the dtsconfig file and unencrypt the variables at runtime.
Nope, not an option.
That is one of the reasons the Project Deployment Model and the SSISDB was introduced. With that, you can natively encrypt and more importantly, decrypt those values to provide credentials at run-time.
This may seem a bit trivial...but how do you go about transforming the db connection for a nopcommerce app as it is deployed to various environments.
The db connection is set in app_data\datasettings.json.
Normally this type of stuff is handled with web.config transforms.
How do you go about setting up build transforms for different environments (dev, test, prod)?
I am also looking around this topic.
In my humble opinion, the nopCommerce config is a pain, because it makes it really hard to do proper Continuous Integration/Continuous Delivery while keeping secrets safe.
At initial deployment you are greeted with the install page. The problem is that the installation process writes a a bunch of files to on server, including datasettings.json, where the connection string to the DB is hard-coded.
This means that when I deploy nopCommerce to Azure App Service, for deployments after installation, I have to make sure NOT to delete "additional files on the server" or the config will be deleted, since these config files written by the installer, are not in source control.
It is really impractical not to be able to use standards ASP.NET connection strings, environment variables or KeyVault.
To answer your question on how you do transformation on the config file, one possibility is to use a PowerShell script to read, transform, and write the config file directly on the App Service instance. There is an API for that.
https://blogs.msdn.microsoft.com/gabeshapiro/2017/01/01/samples-for-using-the-azure-app-service-kudu-rest-api-to-programmatically-manage-files-in-your-site/
https://github.com/projectkudu/kudu/wiki/REST-API
Alternatively, you can modify the source to read from Web.Config:
Change the connection string of nopCommerce?
All,
I have an asp.net (asp.net 2.0) application that allows users to attach (upload) files to records (not much different from typical e-mail client) and then view those attached files later.
Typically, we will store these files on the webserver (i.e. on the same machine in app's directory or in another drive on the same computer). But, ... some of our client's would like to store these files on another computer (their designated file server that doesn't run our asp.net app) and here where the problem is: Since our application runs typically another Network Service account it will not have permissions to a directory on another machine.
The million dollar question is: For this type of setup, what are best options to make this setup work? I have listed some below that could elaborated:
1) Keep the files on the same machine as the app and tell client to use backup software to copy it to the file server at the end of the day (not really real-time)
2) Setup a share on the file server but ... how do I deal w/ security,- in other words, network service account is not privileged enough to copy files to shared folder. Do I?
2a) Run my app-pool w/ more powerful account?
2b) Is this possible? If yes, how to:- Use .net code to change current thread's SID to a more powerful account, copy file, and the switch back to network service.
Another issue with #2 is domain networks where policies are on the domain controller and require additional setup.
3) Other solutions????
I decided to use impersonation for directories that require user logon permissions. Here's a good reference material:
http://support2.microsoft.com/?id=306158
This solution works very well.
I am going to encrypt appSettings in Web.config:
Many ways worked on local, but the issue is I need to encrypt/decrypt webconfig many times on production server, and I don't want to Network admins, to change web.config permissions every time we do this?
is there any better way of securing appsettings?
aspnet_regiis -pe is the method Im assuming you are referring to.
First, this should occur only when you deploy to the server (which you are prob planning on). Secondly, net admins just need to run an admin prompt to do this - they don't need to change permissions on the file. I talk about this a little in the video at: http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DEV333
If you want to secure the appsettings content this way you have to do it. But there may be issues if you want to deploy the web app in a farm. In the case you may have to look at Creating and Exporting an RSA Key Container. Or you can have the appsettings values to a database and read it from there.
I would recommend you have your application encrypt the values after it is started. That will make sure that the values are always encrypted.
Then keep the values unencrypted in your source control tree or the installer files that you use to deploy the application.
You can use aspnet_regiis.exe application that comes with the .net framework(NOTE: every framework is having a different aspnet_regiis.exe application)
If your application is in framework 2.0 you can use aspnet_regiss.exe -pef or aspnet_regiss.exe -pe for encrypting the selected section from your configuration file.
for more information you can refer to the link
http://msdn.microsoft.com/en-us/library/k6h9cz8h(v=vs.80).aspx
Hope the information gets you a resolution!!!!!!
:)
I've collected a (hopefully useful) summary of the ways I've researched to accomplish the subject of this post, as well as the problems I have with them. Please tell me if you've found other ways you like better, especially if they resolve the problems that the methods I mention do not.
Leave connection strings in web.config and use XDT/msdeploy transformation to replace them with settings according to my active build configuration (for example, a web.PublicTest.config file). My problem with this is I merge and bury a few server-specific settings into an otherwise globally identical file with many configuration elements. Additionally, I cannot share connection string definitions among multiple peer-level applications.
Specify a configSource="DeveloperLocalConnectionStrings.config" value for connection strings in web.config, and XDT transform this value to point to one of the multiple environment-specific files in my code-base. My problem with this is I send passwords for all my environments to all destinations (in addition to SVN, of course) and have unused config sections sitting on servers waiting to be accidentally used.
Specific connection strings in the machine.config file rather than web.config. Problem: who the heck expects to find connection strings in the machine.config, and the probability of surprise name collisions as a result is high.
Specify a configSource="LocalConnectionStrings.config", do not transform the value, and edit the project xml to exclude deployment of the connection string config. http://msdn.microsoft.com/en-us/library/ee942158.aspx#can_i_exclude_specific_files_or_folders_from_deployment - It's the best solution I've found to address my needs for a proprietary (non-distributed) web application, but I'm paranoid another team member will come one day and copy the production site to test for some reason, and voila! Production database is now being modified during UAT. (Update: I've found I can't use one-click publish in this scenario, only msdeploy command line with the -skip parameter. Excluding a file as above is the same as setting it to "None" compile action instead of "Content", and results in the package deleting it from the deployment target.)
Wire the deployment package up to prompt for a connection string if it isn't already set (I don't know how to do this yet but I understand it is possible). This will have similar results to #4 above.
Specify a configSource="..\ConnectionStrings.config". Would be great for my needs, since I could share the config among the apps I choose, and there would be nothing machine-specific in my application directory. Unfortunately parent paths are not allowed in this attribute (like they are for 'appSettings file=""' - note also that you can spiffily use file= inside a configSource= reference).
p.s. some of these solutions are discussed here: ASP.Net configuration file -> Connection strings for multiple developers and deployment servers
When using SQL Server, you can also use Integrated Security / SSPI and add the WebServer Computer Login to the Sql Server.
That way you dont have to expose anything in the web.config and you can grant roles to that login like you would to any other DB user.
Though you have to understand the implications and security considerations to be taken, because any malicious code executed as THAT machine will have access to the Sql Server.
with regards
Ole
Use the hostname as key for the connectionstring, that way you can choose the datasource automagically. Make sure the choosing routine is not buggy (change hostname - test!)...
Don't put it in the web.config, write an ini file, that way there is no XML encoding.
Encrypt the password therein, with private/public key (RSA/PGP). Don't ever use cleartext, or a symmetric key, which is just as bad.
Check my following blog post: Protecting asp.net machine keys and connection strings
If you do use Quandary's answer, use a key that's not in the site's folder, just like asp.net does with protected config sections.
We manually approve changes to the web.config that go into staging/production. We use integrated instead of username based where possible, but an option we've used in the later case is to just have placeholders for the username/passwords in SVN.
We've used separate config files in the past, but we have run into other type of issues with web.config modifications, so we have been locking it in a single file lately.