Thursday, 2 July 2009

Website Security (Security Blog #2)

in, but not too far!

Securing a website is essentially a three step process. Firstly you have to decide on your security model, what services you want people to access, whether there are different access levels (e.g. your staff to update stuff, rest of the world to view stuff) and whether you need to have special access for your support staff.

Seconldy you need to lock the server down that the website is running on so only the bits you want are available. You can do this just on the server, but I recommend running a seperate firewall in front of the server (it can be shared) as this provides better security. All our websites run behind dedicated or shared firewalls.

Finally you need to make sure the website itself is secure, and doesn't have any vulnerabilities on it (I'll dicuss the common ones below and explain how they work, and how you can avoid them).

With regards to roles, the first one is your job (in cahoots with your website designer). The second one is down to your web host, or your tech team if you are doing it. The third one is down to your software developer or the providers of the product you bought. Do NOT ASSUME that off the shelf software is secure - I've tested plenty of off-the-shelf packages and found them vulnerable to simple web exploits (see below for details).

Lets start at the beginning:

Security Model

The simplest website (static content, never updated) says 'let anyone view web pages'. And that's it. No FTP access, no mail, no updates, no database, no other access to the server. If the content is all static (i.e. no one can add to it or change it) then this is pretty secure. It's also not very exciting.

Typically a simple business site will have some kind of content management system (CMS) that users can update. This can be open source, bespoke or paid for, and may even be a managed service (i.e. you are renting it). Either way you need to ensure that however you access the CMS it is secured with a good password (see previous blog) that is regularly changed.

Please don't assume that calling the update folder 'slartibardfast' or similar will prevent people finding it - security through obscurity is not security.

As you get more complex with the site, the security becomes more complex. If you require Role Based Access Control (RBAC) then you need to verify that each role can only do what it says - login as a high level user, copy a shortcut from Internet Explorer for something only you have access to and then log in as a low level user and paste the shortcut back in - you should get a nice clean error page, or thrown back to the login screen. You shouldn't get the page that only the admin can see. There is more to it than this, but it's a good simple test!

Lock the server down.

Next we come to locking down a server. This is really best left to the techie people like me, but the basic principle is all about attack surface again (remember that from the last blog?). Turn off anything you don't need, lock down anything you do need. Sample code? Remove it. Some of the most common exploits use things like the standard code Windows used to put into it's Internet Information Server to attack the server - leave it there and you are vulnerable.

Again a hardware firewall helps out at this stage - you may have turned stuff of, but if you only let the relevant ports through (i.e. only let people use a web browser to connect) then you are more secure.

Tools like Retina, Microsoft Baseline Security Analyzer and their compatriots will tell you if your server has any issues - run these tools, do what it says, run them again until the tool is happy or you are happy with the remaining risk.

A particular note at this point about PCI DSS (Payment Card Industry Data Security Standard - you can see why it gets abbreviated). This is something banks are enforcing more and more to ensure that your data is secure, and it covers the whole gamut from network security, website security through to storage and use of the card information itself. If you are storing or handling credit card information expect to encounter this at some point. It even applies to printed copies and manual forms! Particular key points to note are that you CANNOT STORE the three numbers on the back of the card (aka CVV code) in anyway after the transaction (you can keep it whilst the transaction is processing). Not even on paper. The same applies to certain information on the magnetic strip and the PIN and PIN blocks. If you have a database record with their personal details, card number and CVV code all unencrypted then seek help now!

Secure the site itself

There are three primary things you have to worry about (plus a whole bunch of other minor stuff). You already have a secure server from steps one and two, which is only letting people access the stuff you want.

There are plenty of other minor exploits, but the three that always get press are SQL Injection, Cross Site Scripting (XSS) and Dumb Coding.

SQL Injection

SQL Injection is where lazy programmers haven't bothered to validate the data going into their database. *** WARNING: Geek Speak coming up ***

Whenever you access stuff in a database on the internet, it usually gets translated into something called SQL (Structured Query Language) which is fired at a database.

For instance, you click login on your account with your username and password (in this case joe and bloggs) and it sends a command like:

SELECT * FROM USERS WHERE Username='joe' and password='bloggs';

All happy, a bit of data comes back and you are logged in. In English you have just asked the database to give you all the users whose username and password match what you have typed in - if it gets a row of data back, then your details matched and you are logged in. No data back means failed login.

However if you log in as joe with a password of

' or 1=1; --

You get this:

SELECT * FROM USERS Where Username='joe' and Password='' or 1=1; --';

Spot the difference? The Database ignores anything after --, so it processes the first bit of the command. Which in English logs you in as joe without knowing the password! It selects all users whose username is joe AND whose password is '' or 1=1 (which it always true for you maths people).

This would work for any username.

The above exploit also works inside the address in internet explorer. So for instance:

http://mysitename.com/viewproduct.aspx?productid=4

would fire:

select * from products where productid=4

at the database, which can be turned into:

http://mysitename.com/viewproduct.aspx?productid=4 and 1 in (select top 1 convert(int, username + '/' + password) from users);

would fire:

select * from products where productid=4 and 1 in (select top 1 convert(int, username + '/' + password) from users);

Which depending on how the site is setup, either gives a nasty error message or something like 'Error, unable to convert 'joe/bloggs' to an integer'.

Which gives you a username and password to the database...

It gets more complex than this (as you can do funny stuff to enumerate every single item in the database, or if the site is REALLY poorly written, execute any command on the server as the highest level user). All from the form you thought was just there to log people into your site and/or show then a product.

So how can you defend against this? Either you can scan for single quotes and remove them (and hope you don't have many foreigners, especially Irish (O'Brien)). Or you can write your code properly and use parameters (this turns the above statement into [SELECT * FROM USERS WHERE Username=@Username and Password=@Password;] and provides the bits with the @ sign alongside). Note that the latter option is by far the best.

XSS

The second exploit, XSS (Short for Cross Site Scripting - we use an X so we don't confuse it with CSS, which is Cascading Style Sheets which are useful!), works by people updating your site with stuff. If you have a forum, for instance, where people can post messages they can post a message that says something like:

<script language=javascript>windows.open('http://mysite.com/fakepage.html');</script>Hi mum.

When someone else views that page, a window pops up which can look dramatically like your site, but is in fact fake.

More importantly, they can do anything they like inside the script tags, as long as they know a bit of javascript. This includes moving stuff around on screen, redirecting you to other sites and if their browser is a little old or not fully patched, potentially download nasty code to the person viewing the page! Note: that's your customer. Visiting your site, and getting infected by something because your site is poorly written. Not exactly good for business...

This one is easier to defend against, any time you allow user entry you simply replace any > or < sign with the www equivalent. Most pages do this nowadays, and most forums provide this option. However anywhere where a user can add content you should beware of this exploit.

Dumb Coding

Lastly we come to Dumb Coding. This is personal hate of mine, and can represent itself in many ways. It is basically where the developers of the software haven't thought about security whilst writing the site, either because they aren't aware of it (particularly true with older software).

For instance, your users should be seperated from each other and only able to view stuff relevant to themselves - this isn't just common sense, it's also the law - the Data Protection Act requires you to make 'reasonable effort' to protect data, especially if that data is about an individual.

Take for example a site where you can upload a document as evidence (e.g. proofs for a bank loan). If you can view that site at a URL like:

http://mysitename.com/users/viewdocument.aspx?iDocID=523

then someone shouldn't be able to change the 523 at the end to 524 and view someone elses documents(!!) You may think this is obvious, I've tested sites where this is the case (and one of them was in the finance industry...). I've also tested sites where you don't actually even have to be logged in as a user to get to these pages...

Whoever wrote the site didn't bother to put in a bit of code to check that the person downloading the document was the owner/uploader of that document. The same applies anywhere where there is a number or reference point in the URL. This could apply to other users data, stuf you wanted hidden (e.g. retired / deleted products in your ecommerce page) or anything else references through the query string (the bit after the ?).

Other classics are checkouts where boundaries haven't been put in - so you can add -1000 items to the basket and get a credit, or where the payment screen has a box which you can edit for the amount you are going to pay.

Please don't hesitate to drop me a line if you have any questions (or if you feel your site is in need of some checking over!).

Next time we leave the realms of dumb coding and website security and move into something even more embarassing - often called the weakest link in IT Security...People!


HSL LogoRussell Henley
Managing Director
Henley Software Limited
T: 01628 550030 | M: 07770 380004 | email | web | profile | twitter | blog