When it comes to defending against attackers/hackers and nasty people like that, web developers need to pay attention to the following high level areas.
- user input.
- user access .
- application management.
- handling attacks.
However, potential attackers can use this knowledge as a platform for their attacks. For example, if you knew how the your opponent was going to defend, you'd be at a big advantage, wouldn't you?
In future articles, I'll be going into this a lot more in a step-by-step fashion, but for now let's dig into this a bit deeper...
1. User Input
The biggest problem with web sites/applications is that they accept input from the user. Way back in the beginning it wasn't like this - most content was served as static pages, meaning everyone got to the same.
Thankfully, things have moved on a bit since then and we can search, update, order online, perform payments and do all sorts of things from our web browser.
But so can the attackers!
Attackers can craft input to try and get around defenses, to do things on the web server that they are not meant to do and in-so-doing can get their little mits on our data or services.
For example, SQL Injection is one method of doing naughty stuff by crafting user input (in this case a SQL statement) in such a way as to hopefully fool the back-end system into executing the SQL commands.
Listen up: in your software, whether it's web based or not, always check the user input. You should be doing this anyway because users will always do one of two things: either something stupid or something nasty. So protect yourself - always assume that what you get from the outside world, from outside your boundary, is wrong and you need to do some sort of checking.
- Sanitization: Clean up the input. Remove characters. HTML encode.
- Blacklist: check the input to see if it contains known 'bad' terms on a black list. If so, reject it or do something else but don't let it though the door in its current state.
- Whitelist: Only allow input that contains known 'good' terms. for particular operations, you might know what the input should look like so only accept it if the input complies.
- Safe programming methods: Sometimes there's a right and a wrong way to do things. Usually it's better to do things correctly. For example, SQL queries should be parameterized in instead of inline parameters in the query.
2. User Access
If there are pages, services or resources on your website that are not for public consumption, then you need to have a way only permit the desired users access. We need to know that the user is who they say they are.
We are all familiar with the typical login pages prompting for username and password; the annoying CAPTCHAs to determine if we're human; the smart cards used by banks that generate a code for us to login.
Login pages may seem to be simple and easy to protect, but they are one of the areas of your site that attackers will pay a lot of attention. Along with login, there are other related pages such as registering as a user, forgotten password, password change, etc.
Once we are confident we know who a user is, then it is common to allow certain users access to various areas that other authenticated users aren't. For example, this usually depends on a user's role - Administrators are allowed access to certain management functionality that the normal Joe Bloggs user is not.
Again, this is a juicy area for attackers to focus on. If an they can fool our systems into thinking they have higher permissions - muahahahahaha!! (Evil laugh) And why do they spend so much time probing this area? Yes, you guessed it - because developers usually leave some backdoor open due to an incorrect assumption. Remember - never assume anything!!
If you're familiar with web based software, you'll know that sessions are a web server's means for storing information about a user's current online...well, session! As HTTP is stateless, some aspect of state can be stored on the server and identified with a session token. Every communication sent between the client and the server is identified with a session identifier so that the server knows which chuck of session information is associated with that user.
How cool would it be (if you were an attacker!) to use other users' sessions? If for example, James was logged on as an Admin - what would happen if we used the same session token as James?Perhaps the server might think WE were James and allow us add a new user with all the permissions in the system? (I'm resisting another evil laugh here!)
3. Application Management
Web developers get a hard time - sometimes rightfully so. For example, when it comes to application management functionality, testing is sometimes not as rigorously carried out as in other parts of the system. "I mean, they administrators - they'll not be doing anything wrong, right?"
Don't trust everything you see: salt and sugar look the same so sometimes it's better to check before spoiling a good cup of tea or coffee! The input from an admin has the same odds as being corrupt as the next person's. Perhaps even more so because administrators are highly sought after by attackers!
Another aspect is that sometimes the application management pages aren't really locked down as well as they should be - just because a page does not appear in a site's menu navigation doesn't mean it can't be accessed. (We'll see this in another post when we use a web spider.)
Administrators have the power to do some pretty powerful stuff in the realm of a web application, so their actions should be doubly secure. Don't make any assumptions.
4. Handling Attacks
When something goes wrong in a web application, as often does - let's admit it - it's good practice to give the user some sort of indication that all didn't go to plan. Usually this is in the form of a brief, friendly and informative line or two of text.
What we don't want to do, especially in a production environment is throw out a whole exception stack trace to the client's display. Why? That's giving the baddies a head start and revealing information to them that they should otherwise have to work hard to find out e.g. which database is used, details about the file structure, the framework that is used to code the website. In some cases it can even show some of the database tables! :/
When something goes wrong or if an attack is identified, it's good to log as much detail as possible so things can be forensically examined at a later date.
What we don't want to do is to put our log files in a location which an attacker can access. The logs will contain LOADS of juicy good bits such as the HTTP requests, parameters, session tokens, maybe even usernames (hopefully no passwords or credit card information!)
So how should the system identify when an attack is happening? Should it alert an administrator straight away? Or wait and gather more evidence that something is happening?
Such things as numerous requests from the same IP in a short space of time would suggest an attack of some sort is under way. A large number of 'blacklist' requests in a short space of time is another clue. One strategy banks use is looking for irregular activity, such as large transfers or activity from another country. I'm sure a lot of us have had the embarrassment of a payment not going through successfully, only to find out later it was our bank acting on our behalf under the assumption that we were attackers!