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).
Related
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.
Okay so my problem is this:
Firstly, user access to the SQL database is controlled by windows authentication, but the app is doing a second check to set user privilege levels within the app.
When I create a new user in my WinForm client App it asks for a password which I then hash with a random salt, these data are then stored in the users table of my SQL database thusly:
users
username, firstName, lastName, pHash, pSalt, accessLevel etc.
When that user, in a later session, tries to log in he gives his password. I pull the salt out of the database and hash the given password.
Now this is my problem: I'm obviously insecure if I pull the hash from the database and compare it with the computed hash locally.
My App maintains a 'user' object that sets a flag for 'authenticated' and has a property that is set based on the 'accessLevel' column in the users table in the database.
There must be a usual way of doing this - or is my answer, you need to be using the SQL Server access facilities to do this not trying to re-invent it in managed code?
You're right in that you can't trust the client to do authentication or authorization. That must be done on the server side.
In your case when you are accessing the SQL server directly from the client you would have to use SQL servers built in functionality for protecting different database objects.
That's usually quite hard to do in a good way though, so a more normal architecture is to create a separate server application such as a WCF service. The clients access the WCF service, which does the authentication and then is in charge of all database operations.
I have a very basic question and want to know how other experts do this
I have an application with some 100s of users. I have been using SQL LOGINS to authenticate these users. These users have password policy enforced. and I face difficulty when any user's password is expired i.e. i have to reset it from SSMS myself. It sometimes becomes a difficult job along with other tasks that i do.
I was told by some experts that it is a good practice to create my own user table and have all the user details in that table. I have created a user table with following columns.
User Id
User Name
Password
PasswordCreationDate
PasswordExpiryDate
PasswordActive
One simple question. How do my users connect to the database . Offcourse i would need a connection string from the application. That connection string would require a user name and a password isn't it? and I can not get the information from the user table until and unless i am connected to the database.
Another problem, how do i keep track of last 5 password. The policy says that the user can not use any of the last 5 already used passwords.
All this can be avoid if I can get a solution of notifying my users that their Password is due to expire in 'n' days and they must change it before it expires.
What do the other developers do when authenticating their users. Please Guide Me
If you keep your user's login credentials in the database, then for access to sql server itself you may only need one login for the entire app. This login would have full access to your database, because it would be up to your application to enforce access rights.
If you go this route, you need to be aware of two things:
There is still a security concern for larger applications that need to give ad hoc reporting capabilities to users through tools such as Reporting Services, Crystal Reports, Infomaker, etc. In this case, users can use these reporting tools to gain read access to areas of the database they should not be able to see.
If you store your own credential information for your users, you need to make sure you do it properly. That means no plain text passwords. You need a cryptographically secure password hash (not md5!) and a per-user salt. If that's greek to you, best to leave this alone.
Another option open to you is to use Active Directory/Windows Authentication for your database. The trick here is that you still have to set up access rights for all your users. However, you can use Active Directory groups for this to reduce the number of logins you need to create, and it will at least prevent you from needing to reset Sql Server logins by hand, because users will log in with their Active Directory account.
A pretty common scenario amongst web applications is to use one username/password (so only one sql login, typically some kind of dedicated login with minimal rights for the application). This way, connection pooling can be used. This is of course a backend account, configured in the web.config and not visible to the end-users.
The users are maintained as a type of data within the application. Asp.net comes with a solution that is called Membership. User authentication is done against the Membership provider and several classes give you programmataic support for authentication, roles, etc. You can use AD as a provider for example, or forms authentication. Or you can write your own.
Since you are now using a dedicated sql login for each user, you need to be aware that this approach moves data access security to the application level. So this might not always suit your needs.
Ideally you'd use existing Active Directory infrastructure to handle your authentication/authorisation of individual users, and you could then have end-users' credentials passed via the web server to your SQL server (You'd probably need to look into handling the Kerberos "double-hop issue" to effect this).
But failing this, it's easy to set up so that the application it self has a SQL login to access the database in order to retrieve user level authentication information. One-way hashes on user passwords would ensure that even if the app's password is read from connection string, user passwords can't be obtained.
Or somewhere in between those two solutions, where the application has a service account within AD, which has access to the SQL database, in order to retrieve the user account info from within the DB.
Either way, if AD is available you can secure further with Kerberos Service Point Names to ensure database access from only your expected end-point (ie the ASP.NET server).
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.
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.