Saturday, March 19, 2011

Website Security

In building one of my first true 'internet facing' sites from the ground up, both client and server side code, I have started to put lots of thought into possible attack vectors. I'm also pretty new to this stuff, so I ask advice from my friends who have been doing this thing for longer, then I wonder why other sites I visit seemingly ignore basic security measures.

To gain some focus, I'll limit security to API and man-in-the-middle snooping. I really can't do much about 'over the shoulder' peeks or key loggers on  a user machine, or someone on the console. I can minimize impact to the system, hopefully confining the security problem to a single user.


Obfuscation and Salting
Data flows from the server to the client, and unless its a really boring static page, there is likely to be javascript running, and nowadays, some XMLHttpRequests doing GET and POSTS on a servlet API, which means data is going in both ways. Also, 'anyone' can view page source, and probably deduce how to use my servlets.

Obfuscating my APIs is probably not worth my time, though I can try to make them limited to specific functions (no running of arbitrary SQL via a 'POST" for example), and have them require validated sessions/logins.

I can however mangle or obscure the data flowing out of the server to the client, as long as the client simply relays that back without requiring any transforms on it.

For example, the client can request the top most purchased items from a store website. The server can send back 'salted' keys that only it knows how to decipher. The key space can be sparse and large, which would hopefully limit 'just add one' kinds of snooping if using a in-the-open auto-incremented key. The actual SQL tables can have regular ol' integer auto_increment keys though.

Require valid sessions to do any changes.  Using HttpSession in java, this is pretty easy. I can set any arbitrary data into the session, but this is all server side. The client doesn't know I put a user name, or access level, or anything at all into the session attributes.  Once past a typical login/password exchange, a valid session is created, and any further servlet POSTs then require a valid session.

Use HTTPS to protect sensitive data:  A certificate costs money, but if you are serious about security, fork up a few bucks a month to get a certificate. HTTPS is 'the' way to stop man-in-the-middle snooping, which is dirt simple nowadays. Anyone visiting Starbucks with a laptop and some easy-to-find software can grab all the data  being sent and received from everyone else in the room. There are bound to be other points around the internet that might also be 'wide open' for data trawling.  

But don't just stop at HTTPS for a simple login/password exchange or a credit card number. Be sure to wrap any Personal Identity data exchange in HTTPS as well. Any time a user edits or views their address, phone number, 'real name' or similar information, make sure its on HTTPS.

On the subject of passwords, never store a password as plain text in your database. Store a large hash of it instead, for example, SHA-1 or MD5. Gawker learned this lesson last year. Any website that can email you your login AND password information is storing things as plain text. Sites that have a 'reset' password option are probably storing only the hash. And of course, never send the password out to the client. You may also encourage your users to choose 'better' passwords by requiring numbers, punctuation, upper and lower case, while also reminding them not to share passwords across multiple websites.

Run a security audit: I'm gonna at least have some friends look at my code, and if the stakes were high, I might even go to a 'white hat' security firm to let them analyze code and/or try to hack their way in. A small development team might want to occasionally 'abuse' their APIs while in testing, or even hire on a smart QA  person who will play the part of a malicious user.



No comments:

Post a Comment