Mar 8 2010

Low-Tech Application Security

At the February LIPHP meeting, Blake Cornell presented a very informative talk about penetration testing. For those of us who have been creating applications for a while — especially web applications, which was the focus of Blake’s talk — there were a few “oh yeah” moments and a couple of “oh crap, I better fix that” moments. But anybody who has never really done serious application programming may have felt intimidated. Also, while parts of Blake’s talk were web-app specific, there were some ideas that are useful for any application developer, even the novices.

This post, then, is an attempt to rephrase Blake’s most important points, in a way that hopefully any programmer will be able to understand, and in a way that should be useful to all application developers. I will be leaving out the really super-technical, database-specific stuff, and help programmers set a couple of important, attainable goals.

What is Penetration Testing?

Why was Blake’s talk so important and informative? What was he trying to get us to do? In short, any application programmer needs to be sure that the application only exposes the right data to the right user. I shouldn’t be able to update your Facebook status from my computer any more than I should be able to see your account balance by using the ATM. The way we determine whether an unauthorized user can see data he or she shouldn’t see is through penetration testing — the act of trying to break into your own application, or trying to get at sensitive data through means other than what the application developers intended.

Think Like The Attacker

As I thought about Blake’s talk on the drive home, I realized that none of us will write a secure application by accident. Application security happens by design. Programmers who create secure applications, then, must always be mindful that careless coding — especially in the absence of good testing — can and usually does result in unprivileged access. I realized that even I needed to adopt a new philosophy while designing, coding, testing, and maintaining. I realized that I need to think like the bad guy, and anticipate what attacks might occur, so that I can defend against them. If you can think like your application’s attackers, then you’re probably already one step ahead of the game.

Don’t Give Away Free Data

Blake brought a large arsenal of technological weaponry to the LIPHP meeting. He had all manner of JavaScript pausers, and POST data manglers, and all kinds of other stuff, meant to confuse web servers into doing what Blake wants, instead of what the web application programmers wanted. But the most important tool Blake brought was his common sense. Attackers will try to glean any information they can from your application, so don’t give them any.

Blake provided a few examples of how a careless application developer can give away data without even realizing he or she did so. Imagine attempting to log into your Twitter account. You type your username and password into the fields provided, and you see a message that says something like “Wrong password. Please try again.” You might appreciate how helpful this message is, since now you know what to fix, and you can successfully log in.

However, if this were the case with Twitter (it’s not, thankfully), then the application developer seriously needs to learn how to think like the attacker instead of like the client’s friend. Sure, it’s nice to give the user that hint. But what if the user typing your username and password into the site wasn’t you? That attacker has now verified that your username exists in the system. (“OK, but everyone knows my Twitter username already.” Fine. Let’s say this is your bank’s web site.) From there, the attacker only needs an educated guess (“He was married on September 9th…”) or a little social engineering (“Hi, this is Chris from Citibank calling. I noticed some unusual activity on your Mastercard over the past couple of weeks, that I’d like to verify. Could you give me your username and password, so we can fix this up?”) — or maybe a keylogger, or a shoulder surfer — to gain unauthorized access to your data.

The Solution

Here’s why I entitiled this post “Low-Tech Application Security.” The fix to this problem is very easy, and it doesn’t require any more purely technical programming knowledge than what got you in this mess in the first place. Just change the error message. Instead of saying “Wrong password”, use the same error message for right username/wrong password as you do for wrong username; something like “Invalid Username/Password Combination” will do. This message has the intended effect on a real user; he’s going to type his username more carefully the second time, and if the password is really wrong, he’s going to take a minute and figure out what’s happening. (“Oh, I used the other password on this account.”) Plus, this message has the intended effect on the attacker, who has now learned absolutely nothing about your system.

What Next?

I’m hoping this discussion will help a couple of you shore up your applications, and make them more secure.  I also hope to write more in this space about how to design applications — especially web applications — the right way.  But there are certainly a ton of other resources out there you can take advantage of to keep learning about security and application design (and please add more in the comments).  Also, find a local user’s group, and join the e-mail list or show up at a meeting, where you are sure to learn a thing or two about programming.  For instance, I will be presenting my application PHProf at LIPHP‘s March meeting.