Minimizing SQL Azure’s Attack Surface

I was running a Windows Azure Boot Camp earlier this week in Houston, TX when one attendee brought up, what I consider to be, SQL Azure’s dirty little secret. It’s this checkbox:


By default SQL Azure is very secure. Think of it as a server in a block of concrete at the bottom of the ocean, no one is allowed access to it. However, If check this checkbox, it enables other Windows Azure services from within the data center to access my database. If I want to use the online Microsoft SQL Azure – Management Portal (an online equivalent of SQL Server Management Studio) I need to check the box, but what are the security implications of doing so? After all other people, some of whom may not have the nicest of intentions, are hosting their apps in the same data center. Have I just opened an attack vector on my database? Could someone write an app that tries to sniff out and attach other SQL Azure databases running in the same data center? Yes and yes!

What to do, what to do?

I then came up with an idea that I wanted to test out. The first thing I did was to create a SQL Azure database, keeping the checkbox, checked, adding a table and loading a few rows into the table. I then created a second rule in the firewall to allow my laptop to connect. Next I used Visual Studio to create an Azure project with a single ASP.NET Web role that utilized Entity Framework to display the data from the single table on a page. Once I verified that it worked I packaged and deployed the web role and removed all firewall rules.


While I waited for the web role to deploy I tried to connect to the database using the online Microsoft SQL Azure – Management Portal, which failed (as expected):


Once my app was up and running I browsed to it and received the following page (as expected):


So far so good, but how can I let my Windows Azure service access the database while preventing other Azure services from accessing it? The answer is simple. Using the properties section of the Windows Azure management portal for my hosted service, I found the Virtual IP (VIP) address for my service:


Once I had the VIP, I added a rule to my SQL Azure firewall to only allow traffic from this address:


I then tried to access my page again and presto! The data appeared:


What I’ve done is enable by Windows Azure service to access a SQL Azure database, while, at the same, time significantly shrinking the attack surface on my SQL Azure database from all Windows Azure services to the VIP address associated with my service. I’d call that a win.

If you decide to go with this approach, which I think you should in a production environment, keep in mind that if you delete your Windows Azure deployment running in the production slot and then deploy a new version of the app, you more than likely will not get the same VIP address, so you’ll want to update your SQL Azure firewall rules. Of course, you could use the Windows Azure Powershell Cmdlets to automate the deployment and firewall update process, but that’s for another post.