We have an ASP.NET 4.0 Web application that connects to a SQL Server on a separate machine across a LAN. I use a ConnectionString (with SQL Server authentication) stored in my Web.config to do this. Basically, it's a fairly traditional Web-Server-to-SQL strategy.
However, one of our clients is arguing that this strategy is not secure. This client says that we should only connect to the SQL Server through a separate Web Services layer.
I really don't want to rewrite this app just to satisfy this client. What should I tell him? Does any one know how I might best refute this?
Thanks in advance...
Security is always a trade-off. What is the client really afraid of?
Having database credential "in the clear"? I have seen auditors point this out as a potential vulnerability, but really, if someone has compromised your web server they can run arbitrary code against the database, so encrypting database credentials doesn't really buy you much.
Your web app should be using a minimal-rights user to connect to the database, so compromising the web server should only give you the rights to read & update data. How would that change if everything went through a web services layer? Again, there is a very real cost - in complexity, and in performance - by going to a web services layer. Only the client can answer whether or not that cost is worth it.
If this is a web project, you need to change IIS servers running user to a domain user and give permission on sql server to that user.
Than you can use SSPI on your connection string like below.
Like this, you don't need to keep your username or password clearly on web.config.
<configuration>
<system.web>
<identity impersonate="true"/>
</system.web>
and your connectionString
"Integrated Security=SSPI;Initial Catalog=TestDb;Data Source=10.10.10.10"
There are many customers that argue the work of an IT professional, just like there are many people visiting the doctor asking for the medicine instead of what disease they have, because they already know the answer since they read about it on the internet.
I mean, they ask you to build the application and you as an IT professional should know best when your application works as expected. You as a professional should have balls to tell your customer that if he think can get somewhere else better, he should go there or perhaps build the application himself; that's what have done in the past with positive results :)
Regarding security; perhaps for their confidence you can encrypt the web.config and show them, but actually it means nothing; if someone can access the server, they could decode it. On the other hand, someone that want to break in to your database should pass trough a lot of barriers. It's hard to break in, perhaps impossible. Another options is simply blocking connections from outside network the network or ip range or whatever. I think this shouldn't be something to worry about.
There much more and either more realistic concerns to worry about, such as preventing cross site scripting and such common treats.
The client is wrong introducing another tier would not automatically improve security.
In a nutshell use SQL server roles for data access for example the built in data_reader and data_writer roles are a good place to start. Always use the most appropriate least privilege account for the application. If you only need to read data use an account that only has access to read.
Use Windows authentication where possible, if this isn't possible then at least encrypt the connectionstring.
More information on how to do what I've described can be found at http://msdn.microsoft.com/en-us/library/ff650037.aspx#pagpractices0001_dataaccess
One possibility is to encrypt the section in the web.config. So, only user who can access the webserver directly can decrypt this section.
Here is how this works with the help of the iisreg-tool:
http://msdn.microsoft.com/en-us/library/zhhddkxy.aspx
You could enable Encrypted connections in your database and tell the client that the connections are encrypted so fully secure?
To make it more secure, and satisfy your customer you can use Tunneling between your computers.
You setup a server tunneling program where the database exist, and client tunneling programs on the client computer. You connect the one computer to the other via tunneling, and the database connection happens over tunneling.
And everything is exchange high secure (and compressed if the tunneling support it).
http://en.wikipedia.org/wiki/Tunneling_protocol
http://en.wikipedia.org/wiki/HTTP_tunnel
Ps I connect to my server only via tunneling for anything that I do.
I never liked using the web config. The registry is more secure.
Best Practices is to:
Hide the important items of the connection string in the registry
Encrypt the important items in the connection like user names, passwords and server name in the
registry
Access the registry through a class
Build the connection string on the fly and only when needed per page
Error handle every page so the connection string won't show, in case of error
Always close the connections once done. Avoid memory leaks
Always close and reset DataReaders
For additional Security
You can build a separate program to create the connection string and
reference that project as a library inside the solution
If you want to be really secure your client is correct. Send the information to a dll that will communicate with the DB. This is a lot of work
Sources:
From ScottGu # http://msdn.microsoft.com/en-us/library/Aa302406
Scalability:
In regards to scalability: Creating\Editing registry keys across a web farm can be accomplished very easily, with custom admin software.
http://weblogs.asp.net/scottgu/archive/2010/09/08/introducing-the-microsoft-web-farm-framework.aspx
On a final note to all the people who voted me down. Security out of the box is just not enough. Security is an Art and not Science.
Hackers know where the password is stored by default......
ASP.NET 4.0 Fans
Microsoft makes it easy for asp.net 4.0 web sites to deploy registry settings:
http://msdn.microsoft.com/en-us/library/dd394698.aspx
Related
I have developed an app, which more than 2k users are going to use it. This app is connected to a database which contains some data.
I have some questions:
1. Is it ok to use mysql direct connection in app instead of API for just reading data?
2. Is there a way that someone find my server's information (address, pass, etc) from my application?
App is wpf.
Generally speaking (and as with all generalities there are all kinds of exceptions here, in both directions) it's okay to connect directly to the database if one of these two conditions is met:
The app and the database are on the same computer
or
The app and the database are on different computers, but within the same corporate network and traffic between the app and the database is adequately protected.
and if one of these conditions is also met:
The end user owns the app and doesn't share data with other users (they break it, that's their own problem and no one else's)
or
You issue separate accounts with only the necessary privileges to each user (the user owns the credential)
or
The machines where the application is deployed are controlled by the business, where you can securely deploy the application (and the account credentials it uses to connect to the database) in such a way that end users are not able to retrieve the account credentials directly. (The business owns everything).
It is not generally okay to connect directly to a database over the public Internet, or within a local network where traffic to the database is not adequately protected, and it is not generally okay to let end users have direct access to the database separate from the application (and if a user has ownership of their machine, they will be able to get that access).
I also need to expound on what I mean by "adequately protected". This involves a few things:
A good firewall between the clients and the database. In some smaller environments, the firewall on the OS hosting the database itself may be enough.
Measures to prevent MitM attacks on data packets to and from the DB. For traditional corporate networks, this usually means 802.1x is running even on the wired network, and wifi access is similarly protected (a pre-shared key wifi network like you use at home is not good enough, because anyone who can get the key can decrypt your traffic). Alternatively, you can implement encryption that runs from the client all the way into such a protected network. This is what many corporate VPNs are for (a public VPN service doesn't accomplish this for you). You may also be able to encrypt that actual database connection traffic. I know how to do this for Sql Server, for example, though I'm less clear on what direct support is in MySql in this area.
If you save the information inside your application, it can be found. You should consider using an API to handle the data reading. Applications can be reverse engineerd.
Ok, I know that every obfuscated .Net application can be reverse engineered.
And I know that it is better if I go the open source way if possible. But unfortunately I cannot because there is no copyright law to protect me where I live.
So I've come up with a plan to make it harder. Since I'm very very novice regarding the security I hope that you will help me find any loopholes in this plan.
The user downloads the application
The user enters his username/password and starts working
He need to export the results to a specific file format
The application connects to the server, and checks the username/password
The data required to create the file are sent to the server
The server creates the file on the server and sends it back to the user
Now if someone cracks the program by bypassing the username/password check the file won't be sent from the server and he won't be able to get the file he wants, something similar software as a service.
Now I want to know if this is the correct way to go? What suggestions to make it better?
Yes, one way to protect your IP is to hide parts of your application logic on a backend server where a cracker cannot simply remove simple piracy checks - they would need to reverse engineer your API to create their own service somewhere to keep the application working.
Note that while this makes things more difficult for crackers, it is not impossible to do, and there are several games who use this scheme that have successfully been "cracked".
First of all, I took a look to every related topic on her about this issue. However non of them was successful in answering my question fully.
Curently I am working on a desktop app, coded in C#, that requires mysql connection both for authentication and storing user custom lists etc.
I put my test database in my account on hostgator and I connected to it with a connection string that looks like;
public static string cs = "Server=xx.xx.xxx.xx;Port=3306;Database=xxx;Uid=xx;Password=xxx";
Even though everything was 100% correct, the connection wasn't possible until I whitelisted my own ip address.
Now everything is working perfect for me, however the thing is that how am I supposed to whitelist all the users of my desktop app for them to be able to connect to the db.
Is there anything that I can do to allow the connection without having to whitelist everyone?
Thank you in advance
Alex
Yes, that'll probably an MySQL (or perhaps even a firewall) configuration option. I guess though that the hoster doesn't allow everyone to connect to a hosted MySQL service, because of the obvious security concerns.
You'd better write a simple service that runs on the webserver, which will publish the data you wish to share. You can then consume this service in your C# app.
Is there anyway to prevent people from using Reflector.net to decompile my .exe c# application? I know there is a tons of post about this but I don't really care if people can see my code the only thing I want to "hide" is my database connection string.
I am currently using "Settings" in my c# to keep the database connection's info.
I wanted to know if using those string in my project's Settings would prevent people from seeing it ?
I am using DotFuscator in visual studio 2008 but I heard it wasn't preventing people from decompiling my program.
I know I could use a Web Services but my server will be on linux so I guess I can't store web services on Linux.
No. Even if you encrypt the connection string in the program code or in a settings file, you will need to decrypt it, and the program must necessarily contain the decryption key somewhere, which means that someone who is interested enough in finding it will find it, no matter how creative you are in hiding it. Why do you need to hide the connection string? If you are afraid that someone who has your program might call the web services directly and trigger unintended actions, you should look into how the web services are structured, what they allow clients to do, and how the authorization works, and make security improvements there instead.
If your program has the connection string in it, users of your program can get it back out. Even if you encrypt it, they can sniff it when your program connects to the DB server.
If you don't want your users to know your DB login credentials, don't give your DB login credentials to the users. That's the only way.
You could do this by instead giving each user their own credentials, and using the permissions system in the DB server to control what they can or can not do.
As others have stated obfuscation is no real protection for a connection string stored in a client application where the user have access to the binaries.
Don't use a direct database connection from your program unless the user is trusted to use the database directly with the same privileges. Have a service (web service, REST-service, etc) in between that you host on your own server. Linux can host services of any of those types I mentioned (use Mono if you want them in .NET on Linux)
In order to expose your database via a web service using Mono or any other language/framework you can host on Linux you would create a web service method for each atomic operation you want to perform against the database.
An additional advantage over letting the client application access the database directly is that when the client application is using a service between itself and the database you are free to change your data store without affecting the client. You can decide to change the database schema in your database or replace the database with a NOSQL solution or even a flat file.
Having a service instead of communicating directly with the database moves the authentication/authorization requirement one step, so now you need to implement it in the service. Fortunately there is rich support for authentication in a web service.
Take a look at this guide on this specific topic from MSDN. Keep in mind, however that this only shifts the security burned. Now you need to manage the security of the key
Hi i am trying to find the best way (or a good one) to store a ConnectionString (my App will connect to a Database in a Server, it will work with it continuosly) and how to handle with the Admin account. For default all the applications with Login must have an Admin account, right?
I think in that way...
So, you install an App on the Machine, how you will configure the ConnectionString? I think that is wrong asking the user to configure such thing if doesn't understand what it is or it really have to be?
And imagine one day that the ConnectionString have to be changed for any reason, if the Admin acoount credentials to Log in the App are in a Table in the Server, how then it will possible to Log in the App to change the ConnectionString?
This is my problem now... I don't know how this type of things is handled, if are there any rules to handle this, any common way because i am starting to work more seriously with this type of things.
Note: I think that is not important but my App is being developed in WPF.
A really easy way to do DB access security with MS SQL Server is use "Integrated Security = SSPI". With that, MS SQL server authenticates against the Windows user entity under which the database accessing process runs. It all happens seemlessly using MS SQL Windows Authentication without the need to store any usernames or passwords within the application.
Another way to do it is to distribute a config file with the database connection string in it, with at least the password encrypted.
We have many MySQL databases on several servers too, so MS SQL SSPI doesn't cover us.
For server side software I store database connection strings and credentials in a separate XML config file that all the server side software uses. The credentials are arranged topically with all database information encrypted. I use a common file for all the server processes and developed a little encryption / DB config file management GUI so management is simplified and access is universal to all the software using the same code.
For end user software it is too difficult to maintain with local config files because of user maintenance. For "fat client" software I maintain a separate database with encrypted credentials on a server in our DMZ that is universally accessible to anyone havinng that software (there is not that much distributed fat client software.) Our web app software has a consolidated user database that controls access for all users/roles for all apps, and everything is portaled through the one system so it is far easier to mantain the user database.
Frankly, the polyglot system is increasingly ugly to maintain. I would use our main domain LDAP server (Windows ADS), but our company policies keep ALL domain member servers completely firewalled off from access outside our most trusted VPN and thus inaccessible in too many circumstances.
I hope someday to have time to setup a *nix based LDAP server in our DMZ and centralize all credential information there.
With connection strings to a MS SQL server you basically have two options:
Either store a username/password pair in it. Your application has to be able to read it, so theoretically, any user of the application could do the same (he has access to your application, so he can decompile it). Practically, you can encrypt the connection string, with a key stored in your source code or application resources and be quite confident that your users won't be able to read the password.
If you have some users that should be able to use the application and you believe them, and other users that may have access to your application but that shouldn't be able to use it, you can use Windows Authentication, and set Integrated Security=True in your connection string. This assumes you configure your DB, so that the approved users have access to it.
Either way, your connection string should be bundled with the rest of the application. If you ever need to change it, you just release a new version. (This works even for the most primitive version of installation: “copy this bunch of files to a directory on your computer”).
Now, the connection string can be stored pretty much anywhere, the most convenient place probably being application settings file.
If you want to be certain that your users will be able to use only the functionality provided by your application and not access the database directly, you'd have to write something like a web service and connect to the database only indirectly through that.
If you need to store the connection string in a configuration file or somewhere else of your choosing, you might want to encrypt and base 64 encode the encrypted results back into a string. Check here for an Encrypt() and Decrypt() implementation.
It is possible to manipulate files (such as the .config file) during the install of the application. So it is acceptable to ask the user/admin (during setup) for the name of the server (and even for a user name and password provided you encrypt these but I'd rather use integrated security).
For updates of the connection string just make a new installer.
Alternative: store the connection string in active directory or in an other well-known store so all you need to do is change the value in one place.