Popular security flaws within websites

So we’re now into 2014 and websites are starting to become way more advanced by implementing new technologies such as AJAX, fancy web forms and even web sockets. However, little do webmaster’s realise that they’re opening a space for huge security flaws within their websites / web applications / web services for malicious hackers to take advantage of. It could be that a hacker wants to take down your service just for the fun of it, or maybe you’ve become a serious business competitor of theirs and so they want to take down your service as soon as possible so they start making more sales. Or maybe a hacker just thinks they have balls because they can actually do this kinda thing behind a keyboard – when in fact they’d probably soil themselves right in front of you if you tracked them down and confronted them asking why they hacked your website :p

security flaws within websites

There are many reasons why you should be extremely cautious about web security, but that isn’t what this post is about – so let’s move on.

In this post I will discuss the top 5 security flaws I see way too often on the web. I will also give some pointers on how to learn more about these exploits and fix them so your web applications no longer get hacked.

Security flaw #5:

Ajax security exploits

Ajax is a cool technology, but one major problem with it is that people who are implementing it into their websites don’t really understand some of the potential security flaws that pop up from using it.

One rule when creating backend systems:

Never allow user input… If you do, clean the input or do some sort of error checking with it so that it isn’t possible for users to perform malicious operations on your web server!

You should always keep this rule in mind when developing backend code.

Sample ajax exploit vulnerability

Recently, I was messing around with a pretty cool theme changer I found on a website showing off HTML 5 and CSS3 website designs. The website itself looked fantastic, but it’s coding turned out to be a nightmare… I decided to take a look at how the theme changer worked, and to my surprise, it turned out that it sent out an ajax request that set a cookie, followed by another ajax request to read a php file directly from the server’s disk, included it into the page so that the PHP pre-processor rendered it on the fly and then used Javascript to append the rendered html to the page’s DOM. This may seem like a clever method of creating such a script, but this is extremely unsafe.

I was able to perform a Directory Traversal Attack on the server and display the entire contents of it just by going up a few directories. A hacker could do a lot with information about your server, and could potentially screw things up so you have no option but to completely rebuild your server.

Assuming the vulnerable script looked something like this:

<?php
<span class="re0">$template</span> <span class="sy0">=</span> <span class="st_h">'html5-green-theme.php'</span><span class="sy0">;</span>
<span class="kw1">if</span> <span class="br0">(</span><span class="kw3">isset</span><span class="br0">(</span><span class="re0">$_COOKIE</span><span class="br0">[</span><span class="st_h">'TEMPLATE'</span><span class="br0">]</span><span class="br0">)</span><span class="br0">)</span>
<span class="re0">$template</span> <span class="sy0">=</span> <span class="re0">$_COOKIE</span><span class="br0">[</span><span class="st_h">'TEMPLATE'</span><span class="br0">]</span><span class="sy0">;</span>
<span class="kw1">include</span> <span class="br0">(</span><span class="st0">"/home/users/username/public/templates/"</span> <span class="sy0">.</span> <span class="re0">$template</span><span class="br0">)</span><span class="sy0">;</span>
?>
            

I could send the following http web request along with a modified cookie (making the server think that this is a genuine request):

GET <span class="sy0">/</span>vulnerable<span class="sy0">-</span>script<span class="sy0">.</span>php HTTP<span class="sy0">/</span><span class="nu19">1.0</span>
Cookie<span class="sy0">:</span> TEMPLATE<span class="sy0">=../../../../../../../../../</span>etc<span class="sy0">/</span>passwd
            

Boom! We are now able to read any file on a server, or display users of the server – making it easier for us to hack other things.

Advice on how to fix this security flaw:

Just don’t use a cookie for implementing this type of functionality. A simple solution to this problem would be just storing the source of the html file in a database field, rather than reading the file directly from a disk. If you must use an include in this way though, just add some validation for checking if the script should be allowed to include files from a certain directory or something.

Security flaw #4:

SQL injections

One of the most common attacks on websites is SQL injections. You’d think by now that they’d finally start to disappear, but people still tend to forget about them or use deprecated functions (functions that should no longer be used as there are better solutions available) and so huge security holes are opened up to user & application data!

Examples of an SQL injection attack:

There is a fantastic wiki entry on SQL injections, so I’m just going to link you there instead.

All I’m saying is don’t create queries like this, or you’re just asking for trouble:

SELECT <span class="sy0">*</span> FROM users WHERE email <span class="sy0">=</span> <span class="st_h">'$someVariable'</span><span class="sy0">;</span>
            

Why you ask? read the wiki entry, it’ll explain SQL injection to you way better than I will.

Advice on how to fix SQL injection security flaws:

  • Use prepared statements for your queries. Prepared statements are safer than using the standard mysql() functions as they automatically filter user inputs wherever you specify. PDO is an Object Orientated abstraction of native database drivers, so it’s compatible with many database technologies (not just mysql). This makes managing your code easier if you ever decide to port your script for another DBMS software.
<em>// Instantiate a new PDO object</em>
<span class="re0">$db</span> <span class="sy0">=</span> new PDO<span class="br0">(</span><span class="st_h">'mysql:dbname=user_management;host=localhost'</span><span class="br0">)</span><span class="sy0">;</span>
<em>// Prepare a query for being escaped</em>
<span class="re0">$statement</span> <span class="sy0">=</span> <span class="re0">$db</span><span class="sy0">-></span><span class="me1">prepare</span><span class="br0">(</span><span class="st_h">'SELECT * FROM users WHERE email = :email'</span><span class="br0">)</span><span class="sy0">;</span>
<em>// execute the query, passing in the parameters to replace</em>
<span class="re0">$statement</span><span class="sy0">-></span><span class="me1">execute</span><span class="br0">(</span><span class="kw3">array</span><span class="br0">(</span><span class="st_h">':email'</span> <span class="sy0">=></span> <span class="re0">$email</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span>
<em>// fetch results as array</em>
<span class="re0">$results</span> <span class="sy0">=</span> <span class="re0">$statement</span><span class="sy0">-></span><span class="me1">fetchAll</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span>
            
  • Turn off errors from the php configuration, or just be lazy and use the following code at the top of your source files:
<?php
    <span class="kw3">error_reporting</span><span class="br0">(</span>0<span class="br0">)</span><span class="sy0">;</span>
?>
            

This stops people from seeing that a table doesn’t exist, and so it makes it harder to ‘guess’ table names or perform blind SQL injection attacks.

  • Don’t make your table names really obvious. E.g. ‘tbl_passwords’ is more likely to be guessed in a few tries, compared to ‘super_long_table_name_passwords’. This obviously adds some complexity to your website / web application, but it really does make it harder for hackers to perform blind SQL injection attacks on your service – if they ever do find a vulnerability within it.
  • Hash passwords and encrypt sensitive data. This is a no brainer really, but older systems still tend to store data in plain text! I actually gained entry into a pretty big education system created by my local council a few years ago. I only did this to prove a point that it could be done – I was however rather shocked to find plaintext passwords displayed in their database along with my personal email address! This really made me up my game with security of data. Oh and they promised me an award for finding this exploit too – which I never got… Awww. :(

Security flaw #3:

Dynamically coding user id’s into forms.

A lot of people will wonder why this ‘exploit’ is even at number 3 within this list, but believe it or not, I tend to see this a lot whilst browsing website source code. Allow me to demonstrate.

Assuming we have the following exploitable html form:

<span class="sc2"><form <span class="kw3">action</span><span class="sy0">=</span><span class="st0">"update-email.php"</span> <span class="kw3">method</span><span class="sy0">=</span><span class="st0">"POST"</span>></span>
    <span class="sc2"><input <span class="kw3">type</span><span class="sy0">=</span><span class="st0">"text"</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">"new_email"</span>></span>
    <span class="sc2"><input <span class="kw3">type</span><span class="sy0">=</span><span class="st0">"hidden"</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">"user_id"</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">"3373"</span>></span>
    <span class="sc2"><input <span class="kw3">type</span><span class="sy0">=</span><span class="st0">"submit"</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">"Update my email address"</span>></span>
<span class="sc2"><<span class="sy0">/</span>form></span>
            

It looks harmless, right? Wrong. By having that ‘user_id’ field in there, you are basically allowing anyone to change anyone else’s email address. So what you’re saying? It’s just an email address linked to my account right? Yeah possibly (depending on your system) but does your website contain a recover password function too? If it does, you’ve just allowed anyone to gain access to another users account in seconds!

Even Facebook were vulnerable to this type of attack a few months ago! Crazy right? You’ll be happy to know that the exploit doesn’t work any longer, but you can read about how this hack happened on the exploit author’s blog.

How to prevent from these types of hacks within my system?

  • Don’t include a user_id field within forms!
  • Depend on a session instead.

Security flaw #2:

Cross site scripting (XSS) attacks

Do you have a comment form on your website? Yes? Are you validating all inputs as much as possible? No? Well I suggest that you fix this right now as you are prone to users executing Javascript on your page without your knowledge!

Cross site scripting example

Imagine I posted the following string of text as a comment to a website:

<span class="sy0"><</span>script<span class="sy0">></span>
<span class="kw3">alert</span><span class="br0">(</span><span class="st0">"Hello random user"</span><span class="br0">)</span><span class="sy0">;</span>
<span class="sy0"></</span>script<span class="sy0">></span>
            

If the website doesn’t prevent against XSS attacks then I would get a lovely alert box like the following every time that page was visited.

By this point your website users are gonna be like “wuuut? how did that happen?” But in fact, this is actually just the start of the attack. An attacker could go way further than this and steal cookie data from a client’s browser with the following code:

<span class="sy0"><</span>script<span class="sy0">></span>
    <span class="kw3">alert</span><span class="br0">(</span>document.<span class="me1">cookie</span><span class="br0">)</span><span class="sy0">;</span>
<span class="sy0"></</span>script<span class="sy0">></span>
            

I recently discovered a slightly more complicated exploit than this on a social networking website called Unii. The funny thing is that I managed trigger 380 calls of my exploited code in just a few hours! Now I’m not the type of person that would hack a website in this way, but I could have easily stole 380+ accounts in no time. I reported this exploit to the website administrator and suggested a fix for them.

How to prevent XSS (Cross Site Scripting)?

Within PHP it’s really simple. Just do this every time you’re echoing a string:

<?php
<span class="re0">$string</span> <span class="sy0">=</span> <span class="st_h">'<script>alert("Hello random user");</script>'</span><span class="sy0">;</span>
<span class="kw1">echo</span> <span class="kw3">htmlspecialchars</span><span class="br0">(</span><span class="re0">$string</span><span class="sy0">,</span> ENT_QUOTES<span class="sy0">,</span> <span class="st_h">'UTF-8'</span><span class="br0">)</span><span class="sy0">;</span>
?>
            

Security flaw #1:

Sloppy coding and lack of code testing.

Yes, that’s right. The main reason people are hacking your website is because you’re just not testing your code enough before you release it to the wild.

Here are a few pointers that I have for people to create better code for the web:

  • Create automated tests.
  • Ask real people to test your application.
  • Get a decent browser such as Google Chrome and use the network inspection tool to monitor traffic, ensuring no sensitive data is transferred between requests.
  • Create a test site on another domain with the same server setup. Always remember to protect the test site from being accessed by non testers. A good way around this is creating an I.P whitelist.
  • Always test the unexpected. Not everyone uses your system in the same way.
  • Always add limits to functions. E.g. Why would a user need to guess their password 5 times in the space of 1 minute? Is there a bot trying to brute force account credentials?
  • Always Google for multiple code examples and compare your code against them. If your code contains segments from each example you find, chances are it’s going to be less prone to errors.
  • Research information security every now and then. I like to keep an eye on the Information Security website over at StackExchange and look at some of the questions people ask.

Post conclusion:

Perfecting any sort of web project takes a lot of time and patience. I have been working on websites for over 6 years now and I still tend to find new ways of exploiting them.

Hopefully this post will inspire some of you to think more about your coding style and start writing better code to accommodate for some of the unusual (or unthought of) scenarios that I have pointed out above. You should use this post as a reference for when you’re developing new ideas to accommodate for stopping some of the most common website attacks.

Of course there are many other exploits out there, but these are just some of the more common ones that I tend to come across within websites.

My next post will be a guide on how to create the perfect development workflow with GitHub and an Apache server without any user interaction. This post will also cover more security related aspects of web development, so if you liked this post be sure to check it out :)

Thanks for reading!

Joel

DISCLAIMER: I only research security vulnerabilities for my own benefit. I am sharing this information with you so that you have a general security checklist for when developing new websites or services. You should not use these methods for performing unlawful attacks on vulnerable websites. Instead, you should notify webmaster's of the security flaw(s) in their website and point them into the right direction on how to fix their coding mistakes. A link to this post would be a good starting point ;)
    
Leave your feedback