Most of my work these days involves taking over existing projects when a client needs a new development team. I never know what I’m going to get when I start one of these projects, but I’ve built up a decent checklist of things to look into for possible trouble signs.
One key area here is security. Are any default settings left wide open? How much damage can I do to the site without knowledge of the source code? How much could I do with full knowledge of how the thing works? Have all the locks been changed since I took things over?
And for today’s topic, do you actually need a login to use the system?
Authentication simply means the system knows who you are, ideally with a good amount of confidence. There’s a difference between saying “hi, I’m Bob,” and saying “hi, I’m Bob, and my password is XXXXX.” To put it a little more technically, your system should have a login screen, and on all subsequent requests we should be able to tell who you are.
This is usually done with a 3rd party code library (don’t try to make your own, you’ll miss something.) For direct web requests, you’ll usually have a session cookie attached, and that’ll be tied to session information on the server that includes info about your identity.
(Aside: if you’ve got multiple web servers, you’ll need to make sure either that the user always goes to the same one, or that the session info is shared across the server, or you’re going to have a bad time. But I digress.)
So that was step one of the fix: add an API token system to the project and replace the user ID in all API calls with that token (in case it’s not obvious, the token was a much larger number an highly unlikely to be guessed.)
But I wasn’t done…
We now had a system that knew, with a decent amount of confidence, that the user making the request was in fact that user. Unfortunately, the user still had a little too much power.
Picture this: “Hi, I’m Bob, this is my password, and I’d like the balance of my account.” Sure Bob, that’s not a problem. Now this: “Hi, I’m Bob, this is my password, and I’d like the balance of Susan’s account.” Aaaaand the system still said “sure Bob.”
Authentication deals with identifying the user. Authorization is a matter of making sure their actions are allowed. In most cases, this comes down to making sure the object being requested or acting upon belongs to the user. When you add admins and groups to the mix you need to add some nuances, and in some cases “anyone can do anything” is fine, but this app was pretty straightforward and it was mostly a matter of adding some checks to the code to make sure Bob had the right to do what he was asking.
Cleaning up the mess
Some exploits of insecure code can take a bit of work to apply, but many can be done right in the browser (in this app’s case, some of the attacks were just a matter of changing the URL.) The good news is, once you know what to look for the process of fixing these bugs is pretty mechanical. I like to add unit tests around security specifically (if some are already in place I’ll try to make them fail to see if they were written properly) so it’s mostly a simple matter of identifying the insecure URLs in the app and tightening them up one by one.
For this project, things were locked down quickly and they’ve now got a system that’s much more resistant to hacks. If you’re worried about your website being attacked, get in touch and see how I can help!