how to store database password - c#

I am sure there're lots of discussions already, but how to store a password in an application? (I meant not a user password to be stored in a table in a database, but the password to build connection string)
I've seen suggestions like store it encrypted in a flat file such as xml file, then read it +decrypt it at run time. If this application runs on a server, this is a very good choice, but what if the application will be deployed to end-users' pc? i.e. the flat file will be copied to the user's pc. Is this still a good practice? (my instinct is 'NO')
I know the existence of SecurityString, but then I also read in one post that SecurityString can be easily broken into, too.
Is it a good idea to use Password Vault that comes with Windows 7? Is there any good example of utilizing it programmatically? I've seen an example in msdn, but firstly it is labeled with 'windows 8', secondly when I downloaded the files and opened the solution in visual studio 2012 EXPRESS, it failed to open.
Any suggestion is welcome...many thanks.
--update--
Let's say, the application will be running on a handful of PCs within a windows domain. (1) At start-up, the application will do a LDAP authentication (active directory). Only upon successful authentication, the application will carry on, and (2) behind the scene the app can connect to the database, take user input to query the db, and this is where the db passwd comes into the play to build the connection string (no this is not SQL SERVER database so I don't think the option of using windows authentication is viable, unless a commercial plug-in is used).
The db resides in the same domain, and has been set up to allow certain range of IP addresses, and is SSL enabled. In short, it is quite secure in this sense. The only bit that is not yet secure is how to store the db passwd for the application.
What caught my eye was the Mysql Workbench. It will save db connections, including the password - which is stored in a password vault. That is mysql's own implementation of a password vault, and I am very curious as to how it is done.

There is no way to give a password to your users and expect it to remain safe. Even if it is hidden in your compiled application and hashed with a one way hash, the determined will recover it.
Instead you should consider your security architecture.
If you are providing services which your application connects to then you should look at providing some sort of more robust authentication as part of your public API.
If the connection string is for connecting to another part of the distributed software, then you should make the password configurable by the end user and store it in a keyring or other encrypted storage.
-- Update --
It looks like this might be what you are looking for;
http://www.microsoft.com/indonesia/msdn/credmgmt.aspx

If the application is going to be deployed where you have no or little control over the system security, ie, external user pc, then it may be worth creating a user login. Authenticate the user against this login, and then from a relatively secure server use whatever credentials you need to provide data.
This does not guarantee security, but it will be easier to maintain if you need to change the password at some point in the future, or if an individual user is compromised.

Related

How to store SNMP-V3 credentials in a C# application

i am creating a C# application (with .NET framework 4.6.1), which needs to communicate with an SNMP agent over SNMP-V3.
I found myself baffling with the question of how should i store the SNMP credentials.
i obviously cant hash them, because they are needed as plaintext when i'm initializing the SNMP manager, and i also don't want to force the user to enter them every time the application starts, because that could happen a few times per day.
The application is to be deployed on several computers, on a closed network, so i can't access to any cloud services.
I have come up with some techniques i can do this, and can't figure out which is the best for my use case:
prompt the user for the credentials at the installation, or at the first launch of the app, encrypt it using Microsoft's DPAPI, and decrypt it whenever needed for SNMP communications
Same as 1, but encrypt is using the user password (i have a login, and the login password is obviously hashed and salted).
I have found this project on github, which uses the Windows credentials manager- is this a valid option?
To me 2 seems like the most robust way, but i then go into several problems, because i can have many users in the system and i would have to do this for every user, and i am not sure it has any advantages in a security point of view.
The scenario i am supposed to face is one where i have an attacker inside the closed network, but if he has control over the machine running my app, it's game over right?
and if that is the case, why even bother with securing the passwords at all?
Any tips and enlightenment will be highly appreciated.
Thanks.
The only difference I see between 1 and 2 is that 2 assumes 1 encrypts the data unsafely (that is a false assumption, DPAPI encryption is good) and relies on the user password (which we do not know if it is safe). That is why I would discard option 2.
Now into the big difference, that would be DPAPI (options 1/2) vs. Credential Manager (option 3) and looking at this security stackexchange post How secure is the Windows Credential Manager? I would choose DPAPI.
So my suggestion would be, go option 1. My reasoning would be:
Credential Manager seems to be less safe than DPAPI
Relying on the user password strength is problematic because you do not know if it is strong or not.
A minor drawback on Credential Manager (if you finally choose option 3 instead option 1) would be it stores the data in the user profile directory, and accidents happen and it could be deleted by accident.

How To Secure Connection String In Windows Forms

I am creating a windows form application in c#. I am storing datasource and initial catalog in Settings. But in connection string there is username and password also.
Why i am storing in Settings is because at deployment i can easily setup through my software. I want to deployment easy and i want dynamic connection string.
So anyone can guide me to how to store this all thing because setting is normal text file user can easily change it.
I have multi user system.So SQL Server in one PC and all user are in different pc. So i dont think creating a all user in database.
Instead of using SQL authentication, it is strongly recommended to access the database using the Windows accounts of the users. If your app runs inside an AD domain, you do not need to grant every single user access to the database, but can use an AD group for that purpose. See this link on how to enable windows authentication in the connection string.
There are options to encrypt the connection string in the file. However, it will require some effort, as it will add another preparation or deployment step to perform the encryption per machine/user.
In addition, there are no out-of-the-box tools available to encrypt a configuration file for a SmartClient app. So you'd also have to implement the encryption. See this link for details.
Please note that even if you use encryption, at least the current user account needs to be able to decrypt the settings in order to run the program. This also implies that a technically savvy user could create a small application that reverts the encryption and can get access to the credentials this way. So using Windows Authentication is really the better option.

Secure Configuration for a C# Service

hopefully this is a simple one and I'm just failing to find the answer!
I want to write a C# application to run as a service that periodically connects to a SQL Server DB to run a few queries. The connection details for the SQL Server must be stored somewhere that the server can get them, but I don't want them stored in a plain text file. I could store them in an encrypted file, but then password would need to be stored somewhere that the service could access it, somewhat defeating the point.
So is there some kind of application/service-level encryption or secure storage API that exists, that allows configuration/data to be stored securely that doesn't need me to just store a password in a file somewhere?
Cheers!
It is entirely possible to encrypt the app.config (see this blog for some more details). However, an administrative user (or a user who can attach a debugger to your program, or a user who can set up a proxy between your program and the server if the password isn't sent through encrypted) will be able to see the decrypted password.
If you're concerned about that, you should consider a different security model. For instance, you could go with a Trusted Subsystem Model, in which users authenticate against a intermediary service that is trusted to connect to your database. This service could be set up to use claims, role, or user based authentication to authenticate users and determine whether they should have access to the database - and would ensure that you never distribute the password stored in your connection string.
Alternatively, if possible, you could consider utilizing logins and users/groups in SQL Server - which would allow you to use trusted authentication and not require a password in the connection string (although it would still require you to distribute the connection string with your application, and again even if it's encrypted a user of your application who has administrative access to the machine could potentially view it decrypted).
Just note that both of these methods do come with some additional overhead - you'll have to maintain roles/claims/users on some level to make sure that only the users you want are able to connect (not as simple as just always accepting the connection from whoever has access to the application).

How to ensure DB security for a Windows Forms application?

The basic setup is classic - you're creating a Windows Forms application that connects to a DB and does all kinds of enterprise-y stuff. Naturally, such an application will have many users with different access rights in the DB, and each with their own login name and password.
So how do you implement this? One way is to create a DB login for every application user, but that's a pretty serious thing to do, which even requires admin rights on the DB server, etc. If the DB server hosts several applications, the admins are quite likely not to be happy with this.
In the web world typically one creates his own "Users" table which contains all the necessary info, and uses one fixed DB login for all interaction. That is all nice for a web app, but a windows forms can't hide this master login information, negating security altogether. (It can try to hide, but all such attempts are easily broken with a bit of effort).
So... is there some middle way? Perhaps logging in with a fixed login, and then elevating priviledges from a special stored procedure which checks the username and password?
Added: OK, so integrated authentication and windows groups seem to be a fair choice in most situations, so I accepted the relevant answer. Still, if anyone can come up with a non-integrated authentication solution, they'll get an upvote from me.
For WinForms use Windows groups. No passwords are needed because the credentials are inferred from the Windows login using your application.
This is best practice
Basically:
The user belongs to a group (assumes single domain)
Group is a login in the SQL Instance
SQL login maps to a database user
DB User belongs to a DB role
Role has object permissions
It's worth reading up first before having someone try to capture all the information here
Edit:
If you have a workgroup, you can still do it by setting up sqlbox\bob, sqlbox\hans etc in a sqlbox local group.
When someone tries to connect (say bob on his PC) windows will ask them for their details. As long as bob knows his SQLbox account detailsm he can connect.
But then, I've not tried this in a workgroup setting...
In addition to using Windows Domain/AD Groups (put the AD groups in appropriate roles you create in SQL Server, so all account maintenance moves to AD), be sure to use the Application Name in your connection string - this allows you to see which applications are performing operations in the profiler etc.
Because when everyone is logging on as themselves from different applications - windows and web, it helps to know that it's actions taking place through an application and not just any user's ad hoc query through ODBC and Excel, say (if you allow users access to certain views for data export or report writing).
Can't you use Active Directory Groups to make the management of the db connections easier?
From MSDN...
The name can be a Windows user name or a Windows group name, of the form DOMAIN\Name.
That way you may have a few groups, read-only, editor, manager, admin etc. It's how I have achieved similar things in that past with Click-Once apps.
It really is the best choice for what you are doing.
I am assuming this is an existing app? If it was new I would otherwise say to go client server with web-services or similar.
PK :-)
With regards to wanting to hide your authentication and use a single application login with WinForms, if the login has very little privilege - select only on views and execute only on stored procedures, anyone who manages to reverse engineer your encryption of the login information in your application will only be able to perform the same functions they could perform in your application. If you absolutely have to raise the level on the security, you could authenticate each stored proc against your users table (poassing user and hash to each SP). Also, rotate the central application login on a regular basis.
All this is a lot more difficult than using integrated authentication and implementing AD platform in your environment. So you're effectively writing your own directory and authentication instead of using one off the shelf.
In addition to gbn's update about workgroup versus domain, you can run the application with RUNAS /NETONLY /USER:SERVER\USER with user credentials on the domain or server which your machine is not a member of. At the point that the application makes the connection to the database, the remote credentials will be authenticated and used. I have an application which actually checks to see how it was run and if it not run with a particular switch, it prompts for username and password and then re-runs itself using the Windows API using a function equivalent to RUNAS /NETONLY /USER:DOMAIN\USER. This is because our workstations are not currently on the domain (or on a domain with a trust relationship) of the SQL Server. In this case, you could still manage the security in local groups on the SQL Server or groups on the domain of the SQL Server. You would basically just lose out on the automated authentication token.

How do I securely hide database credential in C# application?

I have a situation that users access remote MySQL server in C# application.
Basically,
A user using C# application on his/her desktop ->>>> connects to remote ->>>>>>>> [ REMOTE ]
How do I securely hide database connection detail?
I have few ideas, but I don't think they are safe.
Encrypt database connection data into a file and store it within application directory.
prompt login page and let a human enter username/password, then transfer database connection data to user's computer.
No matter what you do if the credentials end up in the application in cleartext you are vulnerable.
Either implement a service layer in front of the database or if direct connections are essential try and come up with a scheme that allows a unique databse account for each user and then authorise them appropriately on the database.
Generally, it's better to ask the user for the credentials so that each account can be enabled or disabled by the administrator. Barring that, there are APIs for encrypting all or part of the configuration file. Here's a sample article:
http://www.codeproject.com/KB/dotnet/EncryptingTheAppConfig.aspx
I would suggest some form of session management based on user credentials. This can be accomplished in many ways.
For instance, you may accomplish this by simply wrapping your database access with a back-end system. Your desktop clients are oblivious to the database and interact solely with the back-end system. Unfortunately, implementing this level of indirection is not trivial if you have to do it from scratch but it will certainly make your application more robust and flexible. WCF services can help accomplish this.

Categories