I was wondering what the best approach to make secure connection to SQL Server would be? Here is my scenario. At my work, we have SQL Server 2012 Standard. My boss wanted me to create a new DB utilizing TDE. I found out that you have to have Enterprise Edition in order to use TDE. We looked into it and it was going to cost a fortune, so we are not going to purchase Enterprise Edition. So I was thinking about using Stored Procedures to interact with DB. Is this more secure than submitting SQL query across web? Also, what is the best security measure to communicate and transfer data to/from web app/DB server?
Thanks in advance,
Brad
EDIT:
Also, is there anyway to securely send username/password credentials in the connection string?
Stored procedures would in a sense be more secure, since you could simply submit objects into the procedure to generate your desired result. This would mask the underlying SQL statement, so it could be considered more secure. I think most places rely on the Windows Authentication aspect of SQL in a domain environment.
It is fairly secure, more so if your site is wrapped up in SSL. Avoid standard SQL authentication, it's text based and shouldn't really be considered.
Code wise, you probably want a layer in between your DB and your website to do all the heavy lifting. This somewhat obfuscates what your website is doing since it is calling to your middle-man, and he handles all the truly transactional stuff.
Also, how are users going to be interacting with your website? Will they be required to login first, and what mechanism will control this? There are quite a few other design details to figure out before you can really consider which method will be the best balance of security and usability. I'd go for WindowsAuth/SSL and utilize a security account to perform all your transactions. It's easy to setup and AFAIK not easy to hack.
This are two different things - TDE will help you just with encrypting data on file system (so if I have access to filesystem where you have your db I won't be able to read it if you're using TDE).
Communication between application and db is different issue. There are several things you can do:
open network ports for db just to webserver (only from web server ip(s) you can access db)
use integrated authentication (no-one can sniff your password)
embed your business logic into stored procedures (you limit access to db just to function needed for scope of your web application)
However especially the stored procedures part can be pain (ORM like EF, LinqToSQL or nHibernate are just terrible when it comes to stored procedures). And also this approach doesn't guarantee that no-one will be able to see data coming from database server to web server).
If sniffing data between webserver and db server can be a problem, you have to write webservice for accessing data. This webservice should be on trusted network to db server (as close to db as it can be - same box is the best). Webserver should call this webservice over https (thus sniffing data between web server and webservice is impossible) and use authentication to access webservice (recommended is windows authentication).
Related
I am working on a C# winform project and during several operations I save and retrieve data to and from my google cloud SQL database.
In order to implement this, I set up the SQL instance, allowed the public 0.0.0.0/0 IP (so I can use this app from different PCs) and created a database user with a strong password. In the connection string in my c# project I connect to the IP with the created database user + Password.
Now my question is, how save is this? For my project and the enduser it is essential, that the data is as save as it can be. The only safety I have now is basically my google account Password and the database user Password.
Would there currently be a way to bypass that and retrieve data without me noticing?
best regards
Steffen
This was fine "back in the days".
Now, it is good practice to have a front-end proxy that uses APIs to serve data to the application.
If you can build and application that will run in the Cloud, next to your database, it would be best. Have that application authenticate users of the Winform Application and send them the information they need through API calls.
Without this, and having your application access directly the database you will have 2 issues:
lower security
high latency (and this will probably be more problematic). Database requests don't really like latency.
On top of it, you could use that server-side app to cache data and do some consistency checks.
However, for DEV purposes, direct connection is acceptable. Just don't put production data there.
I have an SQL Server running on a Windows 2008 R2 machine which needs to have basic queries run on it (SELECT / INSERT / UPDATE). These operations are executed directly by the client, an application written in C# which installed on one computer in a different location so the connection is over the internet.
Since the nature of the operations run on the DB is so simple, I would rather not write a back-end on top of the SQL Server. So the setup for security:
1) Username and Password written in client and submitted.
2) A (parameterised) query is run on the server and the password hash and salt are returned to the client.
3) The password and salt are appended, hashed using SHA_512 and is compared to the password hash.
4) If the two match you are given access to the toolset that creates and sends the queries.
After researching the topic somewhat I feel like this system has some security flaws, but I cannot pin-point exactly what these vulnerabilities might be.
Based on your scenario I would consider creating SQL accounts for each user of your application. When the user logs into your application use these credentials when constructing the SQL Server connection string and allow the server to perform the credential validation. This is often referred to as pass-thru authentication.
Even better, if your application will be executed by users on the same Active Directory domain as the SQL Server you can use the more secure Windows Integrated Security (what you are currently using for local testing) and the users will not need to login at all. The connection will simply use their current AD credentials. See this link for more information about setting up user accounts in SQL Server using Windows domain credentials: https://msdn.microsoft.com/en-us/library/dd787978.aspx
Also, with either option you will still want to use a TLS protected connection (Encrypt=true) to help prevent snooping of credentials over the wire.
If I understand this correctly, then the whole password-check is done on the client side. Is that correct? If so, it seems potentially insecure.
Do you trust the client itself entirely? If an unauthorized person can get access to the client, or create another client that mimics your client, then that significantly increases the chance they'll gain access to your server side.
It definitely sounds like you would be more secure creating a back end system, even if it is just a very simple proxy-service that simply checks the username and passwords, and then forwards the query itself as-is.
That way, the password-hash and salt will never have to leave the server.
A client connecting directly to a SQL Server is not secure. If the client is on the local hard drive then it can be hacked.
You are not finding tools for what you are trying to do because it is not a good design.
Don't get your logic of "Since the nature of the operations run on the DB is so simple, I would rather not write a back-end on top of the SQL Server." If it is easy then that is a reason to set up a back end.
.NET has a whole infrastructure for it. Windows Communication Foundation.
I have a web-server and a database server. There is a WCF service on the web-server and a website using it. Website requests the data from the WCF service and WCF service connects to the database server, fetches the data and returns it to the website.
To optimize this process and decrease the calls to WCF service I decided to manually cache the data on the web-server. One option I can think of was Microsoft Sync Framework. But then I realized that I have to create a sync framework by myself to achieve my objective. Because Microsoft Sync Framework does not provide any option for my kind of process. My process will be actually like this:
Website requests the data.
Business logic of the website checks whether it is available on the compact edition (sdf) database in the website's App_Data folder.
If present, fetch the data from the compact edition.
If not present, connect to WCF service and fetch the data from main database server and copy it to the compact and then fetch from compact edition.
So what I want to ask, is this technique efficient? and if YES is it there any alternative way to quickly achieve this technique? Or I have to code all of it manually?
It could work, but if it was me, and my goal was the increase performance/cache the calls between your web server and a back-end sql server, I wouldn't choose sql server compact edition for caching purposes.
Something like redis or memcached might be a more appropriate/higher performance way to increase performance of your caching layer. The compact sql server may cut down on the number of calls to your back-end server, but it might do that at the expense of slower response times overall.
It could be efficient in some circumstances, but I could propose you to use presreve data cache in local SQL Server Express instead of Compact.
The type system of SQL Server Compact is different then SQL Server. I know that EF6 support both but I would not start this journey on my own...
In any case there should be reasons why you need to work with cache throwgh RDBMS..
You can also use NHibernate, 2nd level caching. For more information, read this article http://www.codeproject.com/Articles/529016/NHibernate-Second-Level-Caching-Implementation. It will store data in the MemCache, and detect changes to records.
Another caching technology, is AppFabric, and you can see more details here : http://msdn.microsoft.com/en-us/library/ff383731(v=azure.10).aspx
By using memcache performance can be increased.
These are the steps to implement the memcache
You have to create a window service that will retrieve data from database and store in memcache in JSON format as (key value pair).
For website create a handler file as an API that will retrieve data from memcache and display the result.
I have implemented this in one of my project it retrieves thousands of data in milliseconds
After much Google searching and at the risk of asking dumb questions, I could use some help. I’m developing a C# WinForms client application using ADO.NET to read/write data from a SQL Server 2012 database located on the Internet. That same application also needs to upload/download data files. The client application will only be used by a few employees (ever). The employees are all in different locations. The database is only about 20 MB. There will be about 100 data files totaling about 300 MB accessed individually on a periodic basis. SQL Server 2012 is running on a (non-virtual) Windows Server 2008 R2 machine which we have full control over. The client application will be running on Win-XP and Win-7 machines.
Priorities are 1. Internet security – keeping hackers out of the Windows Server machine and off the client/server communications. 2. Performance. 3. Simplicity. Corporate security and scalability are not issues. Also, performance is not that important if the solution is overlay complicated.
Two related questions I could really use help on:
Given the above priorities, what is the best way to communicate with the database? The only two options I’ve found are exclusively; a WCF service or directly through a VPN.
And again given the above priorities, what is the best way to upload/download data files? I’m sure there are many options for this using VPN, WCF, FTP; but I don’t know any specifics. Also, using a SQL Server 2012 FileTable looks promising but I’m not sure how that works over the web. Backup/restore plus being able to do a full-text search over the data would be nice features but not requirements.
I know what a VPN is but have never used one for these purposes. I know there are some security issues with PPTP, but we won’t be upgrading the XP machines for a while. I know what a WCF service is but have never written one. I also don’t know if SOAP or REST is better in this instance. I’ve built a FileTable in SQL Server, but I don’t know how to access the data remotely. I have decent knowledge of C#, ADO.NET, and SQL Server.
I realize these are big questions with subjective answers. Still, any ideas or a shove in the right direction would be greatly appreciated.
Keep it simple and use standard mechanisms. My recommendation is as follows:
Build a WCF service that is capable of performing the operations you want. You can build a SOAP or RESTful service. My general guidance here is to build a RESTful service because you're transferring files and this is much more integrated with REST. With SOAP you have some setting you're going to need to fiddle with to transfer large files.
Use SSL to secure the service, keep it simple. A VPN is an added layer of complexity and very likely not needed in this scenario. Further, it will only make the experience for the users less friendly.
I would not recommend using the FileTable in SQL Server 2012 for your needs. You own the server so when you send and receive files it will be much more straight forward to deal with the file system.
You can also build a simple forms authentication process that creates a session key for the user and passes it back. I'm not sure this is necessary, but if you need that extra layer, just make that one of the operations. Then that session key can then be passed into each method and validated before performing the operation. This will be safe because you're using SSL.
Here is a tutorial that will help walk you through building a RESTful WCF service, and it's fairly new.
My recommendation would be to deploy a VPN server to provide the security you are looking for. There are a number of good VPN servers available, and a Google search should provide a number of options at varying price points.
Once you have deployed the VPN server (and clients to all computers not on your local network that you would like to be able to access the database), you can use ADO.NET to access the database. ADO.NET will work seamlessly behind the VPN.
From the context of your question I am assuming that the files are stored in a file system outside of the database, and the database merely references the files. If this is the case, you could use any number of options for downloading the files, but FTP is a time-tested, easy-to-implement solution. There are others that may or may not work better in your situation (see here for a few options).
I have a question regarding C# Windows Forms connecting to external hosted databases.
I have a GoDaddy SQLServer 2008 database that I use for my web development database purposes. I am creating a C# windows form and I need that to connect to the database. I know how to connect a C# Windows Form to a local database, so I figured that the only difference would be to use a different connection string.
The connection string I am using is as follows:
Data Source=limeoatsdb.db.8996219.hostedresource.com; Initial Catalog=database; User ID=userid; Password=password;
I replaced the values above with dummy values, but obviously in my code they have the correct values.
First of all, is it even possible to connect a C# windows form to a GoDaddy database?
Secondly, if it is possible, any ideas on what I am doing wrong?
This is not possible. GoDaddy blocks all connections to its databases from systems it doesn't manage.
This is typical of many hosting companies. It's common that you can only use their databases from their own systems, for security reasons.
If you need access to your data, you'd need to create some form of intermediary step, such as building an API in your website which could be accessed by your form.
Beyond GoDaddy blocking ports, I should point out this is a bad idea if you plan on distributing the app.
If you allow clients to connect directly to your database, you're essentially leaving the front door wide open. There'd be nothing stopping me from connecting to your DB server with SQL Management Studio and fiddling with your data.
Think of it this way: in a web app, you'd never give client-side JavaScript direct access to your database. Instead, it has to go through your app server.
I'd create some kind of server that provides an API that the client Win Form can call. The server can even be a regular web server that provides REST/SOAP/whatever APIs. A good place to start might be looking in to WCF.
Yes, you can connect to a SQL Server database on GoDaddy servers.
It's a feature I've used to access the database through SQL Server Management Studio.
Check this: https://stackoverflow.com/questions/357147/go-daddy-sql-server-2005-remote-connection
Basically, when creating your database, make sure you check the "Direct Access" option.
Obviously, this is a security issue you must be aware of.