IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Application Servers and DB Security

Wednesday 25 February, 2004, 01:40 PM

In Sam Gentile's recent blog on distributed computing in .NET, he quotes Robert Hurlbut saying:

"What happens when the web server is compromised, and your database credentials are sitting there open for anyone to look at?"

The obvious answer is: "When that happens, I will wish that I hadn't put database credentials on the web server." (There's also a second nearly as obvious answer: "This is why my database is behind a firewall." Or possibly "I will wish that I had put my database behind a firewall." If your database is inaccessible to the world at large, then if an attacker obtains a set of credentials, that doesn't necessarily compromise your security - they also need to be able to reach it on the network. Of course, depending on exactly how your web server was compromised, an attacker might be able to use the server to get past the firewall, but I'll come to that shortly.)

Both Sam and Robert recommend adding a physically separate application tier as the way of dealing with this. I don't really agree that this is necessary, at least not if you're using SQL Server.

With SQL Server, you shouldn't need to put credentials on the web server - you should be able to use integrated security instead. It's true that you may need to jump through some hoops to do this - you'll need your web app's ASP.NET worker process to be running under a distinguished account that will be recognizable to SQL Server. (This means you probably won't be using the default settings. On Windows 2000 you'll be running as the ASPNET account by default, and on Windows Server 2003, the default application pool uses NETWORK SERVICE. But it's easy to change this. And on Windows Server 2003, it's even easy to run different web applications with different identities. Of course for this to work, your web server and SQL Server will both need to be in a domain.)

So if you use integrated authentication and you connect your web server directly to the database, let's see what this does to the question:

"What happens when the web server is compromised, and your database credentials are sitting there open for anyone to look at?"

This now has a different answer: "My credentials aren't there open for anyone to look at. Your question is based upon a false assumption. Nyaah naah, ner nyaah naah!" (Note: this is called hubris, and is quite a good way of encouraging idle hackers to take a pot shot at your system. You might want to consider being more diplomatic than me, because then you'll look less stupid when your system is eventually compromised...)

So you might not have a problem. It does however rather depend on how your web server was compromised. If it was simply that someone managed to trick it into revealing the web.config file, or maybe the code for the web site then you don't have a problem. If you use integrated authentication, these files won't contain credentials. But what if someone has managed to compromise your server sufficiently that they can upload and run arbitrary code?

If I can run my code on your web server, then it doesn't make any difference whether you use integrated security to talk to the database or not. If you store credentials, I can presumably discover them, and if you use integrated security, I can just upload some code that connects to the database. (Since I'm running code on your web server, the database won't be able to tell the difference between the legitimate web application code and my evil code - both will be authenticated. And since I'm running my code on your web server, this will get around your firewall - my code can see whatever servers your web application can see, because I'm injecting my code into your web server.) So I can now do anything to the database that the web application can.

So surely this makes the app-server-for-security argument look more compelling?

Or does it? Let's consider what would happen if I were able to run my code on a web server that didn't talk directly to the database, but which talks to a physically separate application server. This doesn't really offer any more protection - my malicious code can do anything to the application server that the web application can. If the legitimate web application code is allowed to tell the application server to modify the database in some way, then malicious code will also be able to tell the application server to do exactly the same thing. Sure, I have to discover the remote API to the application server, but if I've already compromised the web server to the extent that I can run any code on it, that's a fairly trivial task - I can either use reflection, or just write a custom handler that lets me download the contents of the bin directory.

So, let's compare these two setups. If all communication with the database must be funnelled through an application server, a compromised web server will enable an attacker to do anything that the application server would allow the legitimate web server code to do. If the web server communicates directly with the database, then a compromised web server will enable an attacker to do anything that the database would allow the legitimate web server code to do.

Going via an application server only offers any extra security if the server is able to impose extra restrictions that could not be imposed when connecting directly to SQL Server. But of course SQL Server lets you impose arbitrarily tight restrictions on what a particular user can do to the database. (Not everyone takes advantage of this, of course. But that's a flaw in their implementation, rather than a flaw in the architecture.)

So as long as you stick to the principal of least privilege, and make sure your SQL Server is configured to grant the web application the absolute minimum set of permissions required to do its job, then a compromised web server that connects directly to SQL server is no worse than a compromised web server that goes via an app server. You can avoid granting the web application permission to look at any of the tables directly, and instead make it go via restricted views or stored procedures. This gives you reasonably tight control over what the web server can do to the database. So unless the security policy you want to apply happens to be a really awkward fit for what you can do with SQL Server's access control, the application server doesn't add anything here. (In fact, this can even mitigate in situations where you do store credentials rather than using integrated security. If an attacker steals some DB credentials, but those credentials turn out not to let you do anything that you couldn't have done by just talking to the application server, the possession of DB credentials is irrelevant.)

In a nutshell, the argument that sticking in an application server improves security isn't comparing like with like. Yes, a system with an application server that restricts access to the database is more secure than having the web server connect to the database with a highly privileged account. But that's not exactly a fair comparison. All you're really saying is that restricting what the web server can do to the database is more secure than not restricting it. But that's true whether you have an application server in there or not.

I'm not arguing against application servers by the way. I'm just saying that I think the security benefits typically range from non-existent to marginal. There are other areas where application servers do provide important benefits. E.g., if you have more than one web application using the underlying database, it's useful to make them go through an application server, because it reduces the number of machines that need to be updated if you need to change the data access code. And the same is true for non-web apps - application servers make change much easier to manage than a simple client/server architecture. (There may even be some scalability benefits, although I've seen too many systems with highly specified application server machines sitting at around 3%-4% CPU load while either the database or the web servers are sweating it to believe that this is a given.) However, there are lots of databases out there serving exactly one web application, and for those, I disagree that adding in a separate physical application server tier necessarily provides better security than you can get with integrated security combined with access control in the database itself.

But isn't this 'Defence in Depth'?

(Or, if you speak American English, 'Defense In Depth'.) Some might argue that adding in the application server layer adds security in depth. (In fact Robert makes precisely this argument in a later blog.) In fact it doesn't give you that. If I compromise the web server I don't also need to compromise the application server. Compromising the web server is sufficient to let me do anything that the web server code itself was able to do. If you look at it in a slightly more abstract way, the web server relies on one or more external servers. It doesn't matter what those servers are - they might be database servers, DCOM servers, .NET remoting servers or something else. Regardless of what they may be, if I compromise the web server, I will be able to use whatever services those servers were providing to the web server. And if you used the principal of least privilege in your application server, and made sure that it didn't have unfettered access to the database, then breaking into the application server doesn't buy me anything anyway. Unless you are connecting to the database with unnecessarily high privileges, Injecting code into the web server lets me do through the application server everything I could have done directly with the database connection. So I wouldn't even bother trying to crack the application server.

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk