Trusting Input and Outrunning Lions
By Rhys Wilkins
There's a great article on the MSDN website which looks at SQL Injection attacks in another post. Now, I’d like to broaden this out into a wider class of problems. This might seem only relevant to developers, but I’m hoping that everyone can see a way that this might be relevant to their work. The article I referenced discussed SQL Injection attacks against your machines. However, that’s just one case of mistakenly trusting input. Buffer overrun attacks are another case of allowing input in that can cause a problem. You may also have heard of ‘social engineering’ attacks – the kind of thing where someone calls and requests a password reset for a given account. That’s actually another kind of input, and one that you may trust.
So, now we’ve seen two special cases of a problem, what’s the general case? How can we learn from these cases and generalise into a way to protect our systems? It’s actually quite straightforward. In all of these cases, the problem was an input stream that we trusted. So, what do we do with the input we get from callers? Simply put: don’t trust it!
What does this mean for systems administration and security? Well, if someone sends you a command or a request, block it if you can! If not, then check it out to make sure it’s valid. For instance, if you’re a web-based application that talks to a SQL Server instance, then strip out possible SQL commands, quotation marks, and so on in any input you plan to send to the database. But be careful: I once lived at “Rymer’s Lane”, and I often couldn’t use web-based forms! If you have a web server in your DMZ, have that web server check the URLs it plans to process. Make sure that only network traffic on the correct ports can get to the web server. For most web servers, that’s only ports 80 and 443. That blocks attempts to connect to its file shares, or send it network popup messages. Similarly, for your Exchange server’s SMTP gateway, only allow traffic from known mail hosts if you can, and only to port 25.
Next, filter. Use the IIS tools to filter invalid URLs. Alternatively, put the web server behind an ISA Server that can filter those invalid requests. Likewise, hide your Exchange organisation behind the ISA server, so that can filter invalid requests that bad guys can use to harvest valid emails from you for spamming. Use ISA Server or firewall technology to ban traffic over ports that you don’t want to expose. This might mean having internal firewalls within your organisation, because sometimes there are people on the inside trying to get more privilege.
What about those annoying social engineering attacks? We have a neat solution for those, too. We never allow someone to call and have a password changed. The technician always calls the user back. Here’s the key: they will only call back to either a valid internal number or to one of our office numbers. Luckily for me, all of our company mobile phones have internal numbers, which have a gateway into the head office switchboard. Thus, they can call an internal number to reach me, and thus verify that I am who I say I am. Therefore, the technician can always call me on an internal number to verify my identity. It’s not perfect, but for someone to impersonate me, they’d have to steal my name and my phone, then know who to call for a password reset, then somehow attach to the corporate network, and…
So, to sum up – all input should be untrusted until proven otherwise. You have many options on what to do, depending on where the input came from. If it’s a phone call, call back to a known number. If it’s an email, or a web site, check the certificate or digital signature. For other things, you’ll need to work out how to validate the origin. If you can’t validate it, then don’t trust it! Check the input, sanitise it, validate it, check it again, then process it carefully. There’s a valuable concept here, called the ‘Path of Trust’. This is how digital certificates work, for example. I may not trust you directly, but if Steve says you’re OK, then I will, because I trust him.
Interestingly, this is part of why people say that Internet Explorer and related components are ‘full of holes’. It would be more accurate to say that IE is the application handling most of the untrusted input that we deal with. This is because most of the untrusted content out there arrives as either web pages or unwanted emails. IE and its components have to render most of this, and so take a major pounding. I am sure that we would see issues in any complex application that spent most of its time having to deal with untrusted input from a wide variety of sources! A good strategy here is to protect IE, perhaps by putting it behind an ISA 2004 proxy server. The proxy can then filter content, to protect IE. This allows safe browsing without reducing IE’s ability to enable compelling Intranet-based content. Even so, make sure that you keep systems patched up to date, managed correctly with group policies, and so on. This ensures that you benefit from a strategy known as ‘defence in depth’. That is, the more checks that you have, the more likely it is that untrustworthy input will be filtered out somewhere along the line, before it can cause a problem.
The intention of all of this is to deflect attacks from your systems to somewhere else. If your systems are harder to break, then the bad guys will go somewhere else. My broadband link gets hundreds of hits per day, but my firewall blocks them off. So, the bad guys try someone else’s machine, and attack that one instead. And what does all this have to do with lions? It’s very simple. Imagine you and I walking through a jungle. Suddenly, a hungry lion appears. You notice that I’m changing out of my smart shoes into a pair of training shoes. “You’ll never outrun that lion!” you point out. “Ah, but I don’t need to!” I reply. “All I need to do is outrun you!” And so it is with security.