Saturday, 02 April 2011
LizaMoon–Injection and Cross Site Scripting attacks

Following the news on the LizaMoon injection attacks which have been publicised a lot in the press lately really made me want to find out more. Being a technically minded person I wanted to scrape past the general media version of what was happening and get down to what this means to people who run websites that might be vulnerable.

Reading posts on Stack Overflow it seemed to be the same old vulnerabilities that have been around for a very long time were once again being exploited.   Even though I have checked many sites I have worked on in the past, you can't help but wonder if there is anything you have forgotten. Security vulnerabilities in websites is not something you can say "yes I fixed it" its an on going battle (a bit like an arms race) where you have to keep up to date with the latest vulnerabilities.

One of the classic vulnerabilities I have seen from such attacks in the classic query string SQL injection attack. Take for example the following url on a website.




There is nothing wrong with the above urls as long as what happens behind the scenes makes sure that whichever SQL database you are using be it MySQL or MS SQL Server is protected from bad input. Basically you cannot trust any input you get from the web.

One of the things I like doing with the above type of input before I even reach SQL is to ensure that the query string I am being sent in this case messageid is an integer. So in what ever language you are coding in, a very simple step is if messageid is indeed intended to be a query string test it to make sure it is. If you find it is not a query string you can either boot the user back to the page they came from or just send them to a generic error page that basically says that you can't understand what they wanted to do. Never display a detailed error message that divulges SQL statements and lines of code.

If messageid is supposed to be a string such as say a GUID? Test that all the characters used in the GUID are in a whitelist of acceptable characters first so for example accept A-Z, a-z, 0-9 and -  and reject everything else. In addition you can also HTML Encode or escape the input before sending it along to your code that persists it to SQL. In your code that does SQL persistence you can also help prevent such attacks by trying to use parameterised SQL statements instead of building your SQL update or insert statements as strings.

Other methods I have seen being used (although not a fan of) is where no text input is expected is to literally remove words and symbols such as "update", ), (, ',"insert" and "delete" this however can only be done where you definitely know these words are not intended as text values in a table field. If not used properly this could backfire and you could end up loosing data in sentences a user may have been innocently entering into a system.

The other thing to remember is just because the content went into the database safely doesn't mean that when you display that same content back to the user its going to be safe. Take for example a message board that uses a SQL server to store its messages, its pretty easy to escape what a user enters so that its perfectly preserved in SQL. Lets for example say that happened to be some JavaScript and that the JavaScript functionality was to redirect a user to a malicious site.  If you do not HTML Encode the message board text when displayed in the users browser you are basically putting users that trust your site at risk. HTML Encoding what you display to the user ensures that the user sees text of what is being presented and that the browser doesn't suddenly kick in and starts to execute the code its been given. Remember that this is just about any text you display to the user including the browser title tag which may be  something like this..

<title>Does anyone know how to make green widgets?</title>

The above if not encoded could quite easily be changed to the following by a malicious user post on your message board.

<title>Does anyone</title><script>document.location='somesite'</script><title></title>

The code above could potentially redirect a user to a malicious site.