How to Hide connection string in windows forms application - winforms

as you guys know that the Hardcoded coding in exe file can easily be seen through some Softwares (e.g. code reflector), I want to know whether how can I Hide my connection string having information of sql server username and password to connect to database in windows forms application from being seen through any code reflector so that any one else Except me may never be able to use my application without my permission.

As commented, you are better off using Integrated Security, however if you are targeting a SQL Server with say Mixed Mode Authentication you could use the Data Protection API to encrypt the connection string in the app.config. Here is a great article on the topic:
Protecting application secrets, such as database connection strings
and passwords, requires careful consideration of a number of pertinent
factors such as how sensitive the data is, who could gain access to
it, how to balance security, performance, and maintainability, and so
forth. This article explains the fundamentals of data protection and
compares a variety of techniques that can be used to protect
application settings. The author discusses what to avoid, such as
hiding keys in source code and the use of Local Security Authority. In
addition, he presents some effective solutions such as the Data
Protection API.
Safeguard Database Connection Strings and Other Sensitive Settings in Your Code
How To: Use DPAPI to Encrypt and Decrypt Data (C#/VB.NET)

Related

DB Data Encrypting, SQL injection and Intranet

Quick question:
Is it worth the extra time and effort to encrypt Dbase data and guard against SQL injection when you are working on code that will serve only on a local intranet and where only two employees (non coders) are authorized to make use of it?
Short answer - yes, it is.
Attackers look for weak links, and you don't want your application to be a weak link. For instance, if you do not encrypt user credentials in your database and don't guard against SQL injection, an attacker who can get onto your internal network can easily steal the credentials of your users; if they have re-used passwords, this means the attacker can now use those credentials stolen from your "weak" system to gain access to a much "stronger" system.
Also - this is the way we're building web applications now; any framework you use will make the additional effort almost minimal - arguably, not doing these things is more effort than doing them if you use tools like Ruby on Rails, the Zend framework etc.
Its not about one or two user but basic sanity. You don't need to encrypt complete data but only sensitive data like user credentials. Secondly for sql injection its very minimal line of code that you have to use, instead of normal statements use preparedstatements for query. I don't see any hurdle here.
If you store data in normal format, anyone having access to DB can retrieve operator credentials and anyone having access can jeprodise the user data by using sql injections.

storing original password text

My web application stores external website login/passwords for interaction with them. To interact with these websites I need to use the original password text, so storing just the hash in my database is not going to work.
How should I store these passwords?
Edit:
I am concerned if someone gets access to my server. If I use some kind of 2-way encryption and they have server access then they can just check how the passwords are decrypted in my backend code.
It seems to me that you want to store passwords in a similar fashion as Firefox and Chrome. So why not look at how they do it?
This is how Chrome does it:
http://www.switchonthecode.com/tutorials/how-google-chrome-stores-passwords
If you MUST do this, you should use a two-way encryption. There are a lot algorithms (ciphers) for this, but basically you encrypt your data with an encryption key, and use the same key for decrypting them again.
Choosing the right cipher depends on which are supported by the programming language of your choice, but examples are:
Blowfish
3DES
Skipjack
They come in different complexity and some are harder to crack than others. You should realize though, that no two-way encryption is safe from cracking, given enough time. So it all depends on, how sensitive these passwords are.
/Carsten
Decide what you are protecting them against. Options include (but are not limited to): Accidental disclosure, disclosure by you, disclosure in transmission, disclosure due to code error, disclosure due to physical theft of hardware, etc.
If this is a web application, and each user is storing his/her own set of passwords, then you might encrypt these passwords with their login password to your application. If this is an application that each user installs separately, and which keeps its own local database, you could have an optional master password (like Firefox does).
If you are just ensuring that the data is safe if the hardware is stolen, you might use a full disk encryption solution like TrueCrypt or PGP WDE, or Ubuntu, Debian, or Fedora's built-in approach, and require a PIN or password on every boot.
If you just care about secure transmission, have code to ensure that you use transport security, and don't worry about encrypting the data in your database.
I would go about this in the following way.
Protect data against hardware being stolen:
Use disc encryption as discussed in previous posts.
Protecting data if server is compromised (hacked):
I would use two different servers for this project, one worker server and one front server.
A) Worker server
This has the DB with passwords etc,
it also connects to other services.
To connect to worker server, users
can do it through an API. API should
have on function, insertUserData,
which allows userdata to be inserted,
API escaped all the input.
API uses
a DB user which only has input
privilegies on the userData table.
This would be the only way to contact
this server.
Only allow SSL
connections.
This server in turn runs chron jobs that connect to external services, pulls data from them and populate it's DB. Use a different DB with different user privileges.
This server runs another chron JOB which connects to the front server and pushes new data to front server.
Minimal amount of services running
Only SSH/SCP from your IP, tight firewalling. Block if connections exced X / min etc as they only would do an occasional insert.
NO FTP etc.
B) Front server
Receives data from Worker server, never uses the passwords itself. Only way to contact worker server is through API mentioned above, only for new user information. This is where all users login to see their information etc.
The problem with doing it all on the same server, if you get hacked the hacker can sit and sniff all incoming data / passwords etc.. so even if they are stored / encrypted / decrypted securely, with some patience he would sniff them all.
When the application is first run, it will generate a random key. This key will be used to encrypt and decrypt sensitive data. Store the key in a local file, and set the file permissions so that nobody else can read it. Ensure that the user running the web server has no login access (this is a good idea anyway).
Possible ways to break this system:
Get root access.
Get sudo access.
Deploy a malicious application on the web server - this application will then have access to the key, and may be able to send it elsewhere.
As long as you take reasonable precautions against all of these, you should be OK.
EDIT: Come to think of it, you could just store the sensitive data right in the key file. Encryption would provide an extra layer of security, but it wouldn't be a very strong layer; if an attacker gets access to the file, chances are good that he also has access to the DB.

Protecting connection string from Man in the middle

In my winforms application i am hashing the connection string in local level.
But here a couple of questions.
After my app decrypts the connection string, the connection string info is sent in clear text? And since my app is installed locally the man in the middle could be ANY user?
How can i protect the connection string, becides the "force encryption" option, which requires an extra certificate?
You have only a limited amount of approaches here with regard to keeping your connection string safe and secure.
One option, if your connection string is stored within a web.config or app.config file (for web and windows apps, respectively) you can encrypt the value. Here's a couple of links that detail how that can be done:
Encrypting Web.Config Values in ASP.NET 2.0
Encrypt Connection Strings in VS 2005 .config Files
Of course, as you quite rightly say, this may not achieve the security that you desire, since the application may well be running on the user's machine, and thus the app.config file (even in an encrypted state) and associated encryption/decryption keys will also be available on the user's machine. A knowledgeable and enterprising user could then gain access to your "plain-text" connection string.
IMHO, one of the best ways to prevent your users from seeing your database connection string is to never give it to them in the first place, encrypted or not. This would require that your windows forms application does not talk directly to a database (using a connection string), but rather would talk directly to (eg) a web service.
Of course, you'd give the windows form application a URL with which it could access the web service, but then usage of this web service would be restricted and controlled by only allowing access with a user specific username/password combination.
This way, you can host the web service (doesn't have to be a web service - it could be a remote application that your windows form's application would communicate with over .NET remoting or WCF) on a physically separate server/machine that you do have complete control over and protect this machine with perimeter security.
It would be the applications and services that you have running on this secure machine that have access to the database's connection string, and this connection string need never be divulged outside of the perimeter of this machine, thereby keeping it completely secure (assuming the aforementioned perimeter security is in place and is effective).
Of course, implementing all of this would almost certainly mean huge architectural changes to your application, which, depending upon the size and nature of your application, may or may not be worthwhile, however, the only way to truly secure your connection string from a user (or a user's machine) is to ensure that it is never available (in encrypted or decrypted form) to the user (or user's machine).
As soon as you put the connection string on the user's machine, even in an encrypted state, you need to give that same machine that ability to decrypt that encrypted connection string, and there is the weak link in the chain and the point at which (to a resourceful user) your plain-text connection string can be determined. You could off-load the decryption of the encrypted connection string to another (secure) machine, but that's just a variation of the previously mentioned client-server mechanism whereby the part that is kept secure (decryption key, connection string etc.) is performed on a different machine under your own secure control.
you can't protect the connection string. what you can do is connect via SSL secure channel.
This page in the MSDN describes how to implement SSL for the connection:
http://support.microsoft.com/kb/316898
And this one describes SQL Authentication (for ASP.NET):
http://msdn.microsoft.com/en-us/library/ff648340.aspx
It seems that you only really need to encrypt the username and password? In which case, Windows Authentication should be an option (although I often have problems getting it to work for me)

What is the best way to keep passwords configurable, without having them too easily available to the casual human reader?

I have a database that many different client applications (a smattering of web services, some java apps and a few dot net applications) connect to. Not all of these are running on windows (Sadly, otherwise it would make this an easy answer question with just enabling windows authentication for database connections). At the moment, the passwords are stored in various configuration / properties files lying around the systems. Ideally, only the support staff have access to the servers where the files are running, but if someone else gains access to one of the servers, they would have enough database permissions to get a fair whack of data as it stands now.
My question then, What is the best way to keep the passwords configurable, without having it too easily available to the casual human reader?
Edit Just to clarify, DB server is Windows Server 2003, running MSSQL 2005.
PS: I don't see any questions that this duplicates, but if there are, please feel free to close this one.
I'm assuming you want to hide the passwords from casual observers. If they were evil, steely eyed observers with access to all the source code on one of the machines that connects, then they can get the password with a bit of reverse engineering.
Remember that you do not need to use the same protection for each different client. A few steps:-
Create different database accounts for different systems that access your database
Limit access on the database to only what they need using your inbuilt database GRANTs
Store a triple DES (or whatever) key inside a password manager class on your database. Use this to decrypt an encrypted value in your properties file.
We have also considered having the application prompt for a pass-phrase on startup but have not implemented this as it seems like a pain and your operations staff then need to know the password. It's probably less secure.
Let's assume the following common scenario:
You use the same code base for all environments and your code base has the database passwords for each environment.
The personnel (sysadmins, configuration managers) that have access to your production application server are allowed to know the production database passwords and no one else.
You don't want anyone with access to the source code to know what the production passwords are.
In a scenario like this, you can encrypt and store the production passwords in property files that your application. Within the application you can include a class that reads the passwords from the property file and decrypts it before passing it to the database driver. However, the key and the algorithm used to decrypt the password are not part of the source code but rather passed to the application as a system property at runtime. This decouples the knowledge of the key from the application source code and anyone with access to just the application source code will no longer be able to decrypt the password because they do not have access to the application's runtime environment (app server).
If you are using Java take a look at this for a more concrete example. The example uses Spring and Jasypt. I am confident that some thing like this can be extrapolated to other environments like .Net
At my old workplace we used to have a system whereby all passwords were encrypted (using Triple DES or whatever we were using at the time). The passwords were often stored in properties files (this was in a Java system).
When the password needed to be changed, we could simply use "!plaintext" as the value, and then our code would load it up, encrypt it, and store the encrypted value back in the properties file.
This meant that it was possible to change the password without knowing what the original value was - not sure if that's the kind of thing you were asking for!
It sounds like there is no easy answer (because of the different types of applications that connect)... really, the only issue I see is the Java Apps which seem to connect directly to your database. Is that correct?
If so, here's what you can do:
1) Change any client-side applications that connect directly to the DB to go through a service. (If they have to connect directly, then at least give them a first step to "get password" from a service, then they can connect directly).
2) Store the passwords in the web.config file (if you chose to do .Net web services), and then encrypt the "connection strings" section of the file.
Don't use passwords, server to server authentication can usually be performed by using a key file or a client cert or some other way other than a password.
You could use a reversible encryption algorithm e.g. Blowfish to store the passwords as a stopgap measure. There should be a number of free libraries you can use to build this into all your programs that need this access.
Bruce Schneier's page on Blowfish
Wikipedia article on Blowfish
For the java stuff, if you're using an app server see if you can define a data source, and your apps can get at the data source using JNDI. That way, managing the datasource (including connection details) is handled by the app server, and your application code has to do is ask for a datasource.
NTLM Authentication or LDAP-based (Active Directory) authentication should be available to you with a bit of effort. This would allow you to use your "windows authentication" across applications.
It may mean a bit of a migration for your operations staff, but SSO for a set of applications is nice.
Yes I have to agree with the option of storing the (salted) hashes. I would recommend a (salted) SHA256 hash of the password stored in the database. Also don't forget to enforce secure password rules.
My interpretation of your question is that you are asking specifically how to store configuration passwords that your code will use to connect to services it depends on such as a database or third party API. In that case, you may want to consider using a service which provides a secrets container such as Hashicorp's Vault.
You can think of vault as a web service your application can connect to in order to lookup the secrets your application needs at application runtime.
As an example, lets assume your application needs to connect to a database but you don't want to store your database credentials with your application source code in your version control system. Furthermore, lets assume that you want the database credentials used by your application to be different each time your application starts. In this case, you could enable and configure the database secret back end in vault. This means that vault will dynamically create your database credentials as a service, and then provide your application with a revocable leased token for some duration of time. Vault, of course, will allow you to store any secret in it.
Vault provides secure ways for your application to connect to it. One such authentication method uses what is known in vault as the Cubbyhole Secrets Engine.
Using encryption is not a good idea. If someone compromize the key he can decrypt it. Use a hash algorith with salt to store paswords. Hash algorithms are one way so its not reversible. But they are vulnerable to dictionary attacks so use salt (concatane plain text with something long and verbose than hash it). It also protect database from internal attacks.

What is the best way to centralize and secure connection strings?

What is the best way to centralize and secure the connections strings used by applications? In my environment we have many internal applications. Each application requires one or more connection strings in order to access the database. We have a goal of centralizing all these connection strings (particularly SQL logins and passwords) so we could change passwords in one place instead of in 35 different .config files, registry entries etc.
Currently we are using a home grown component which pulls the connection string information from an access database, this covers the centralization requirement but isn't particularly secure. In addition we have applications written in languages from classic asp, vb6, delphi, c++, .net so the solution would need to be usable by all those applications.
Does anyone have an idea of how to do this better, or do we need to rework our whole approach to the way our applications access the database.
The company I work for has used a similar situation through a SQL Server database instead. We ended up creating a COM-compliant .net dll to simplify and secure the API into the database and to ensure that the same logic is used between classic asp, .Net, and DTS packages. It has worked out great for us for year and while there are some refactoring items a lot of us would like to do with it, it's been great to address issues like server migrations or renamings.
I think you are on the right path; however, I would recommend the following changes:
Try to move to a true database server. Access is great for MS Office but not for something of this scale.
Build an administrative console that allows for auditing of who is adding and editing information (secure who has access to what settings too).
Build a COM-compliant DLL so that it can be consumed by other systems in a secure and consistent manner.
EDIT:
Something that I have noticed after working years in a system like this is that it ties your hands slightly on some solutions. Many tools out there (i.e. nHibernate, Elmah, etc. in the .Net world) really are limited when the connection string is no longer in the config files. Many can be easily modified to use your API; however, it is something that takes more time to investigate if you want to use it. Just a FYI on that.
You can use Windows server to create users that are allowed to access your SQL Server database. Then you can use integrated windows login in connection strings.
BTW Storing passwords in public MDB renders them irelevant. Same as they don't exist.
Is it not possible to move to Window Integrated Security in the connection strings, then you do not have to worry about the security aspect as much (unless you need to secure the actual location of the connection I guess).

Resources