Ever wondered how a hacker can get unauthorised access to websites? In easy words, by exploiting vulnerabilities. And guess what, it’s you, the programmer, who creates these vulnerabilities and overall making it easier for any bad guy to hack into your website. Now this may sound ridiculous that how the programmer can be at fault, after all he’s the person burning candle from both the ends, but imagine a scenario in which you are asked to create a website that includes a user dashboard, which allows user to update his information and profile picture, along with a button to delete the profile. Now, before we even begin to roll, you must be comfortable in coding a website with above specifications and able to convert pseudo code into real code on your own, in your choice of language.
A website like that would be easy to make but here’s the golden rule, achieving functionality just means that you’re done with 20% of the work. The rest 80% is all about optimising the code. Let me give you an example, imagine you are supposed to make a program that takes in name and phone number of 100 people and then it displays them. At one point in history, there would have been a time where we didn’t have any loops and people would end up writing same input and output statements for 100 times with 100 odd variables. And then someone, frustrated with the repetition, created the concept of looping and now we can wrap up those hundreds of line into a mere five lines of code. Do you see a point? Both the programs can get the work done but the second program is efficient too.
Getting back to the point where we started, which was about creating a user dashboard. Here we have multiple ways to tackle the task and here’s what you’re expected to achieve (assume the user is already logged in):
1. Create a HTML form with relevant fields (including profile picture upload field)
2. Form will also display the current values that the fields hold
a. If user clicks on submit: Put updated form’s details in database and shift the uploaded file to server after renaming it to user’s ID. Also redirect back to user dashboard.
b. If user clicks on ‘Delete profile’ then delete the user from database using POST method.
That looks pretty easy and if you implemented it the same way, then take a minute and think that what exactly is wrong with that code. And yes, that pseudo code will get the work done.
Here actually lies a severe vulnerability because there’s totally no validation of user’s input and we’re expecting the user to go along the pattern that we want him to. Unfortunately, not every user will have the same pattern and some (a.k.a. hackers) will try to mend it. Think from a hacker’s (which mostly consists of script kiddies because real ones are busy printing money) point of view and you’ll realize that following are the most commonly exploited vulnerabilities which arise due to poorly written code.
Checking the uploaded file’s extension
You asked the user to upload an image and the user uploaded a file named “DSC_002.jpg”. He then checks the URL of uploaded image which is www.example.com/image/id_87.jpg (remember: you programmed it to rename the files to user’s ID). Just to be double sure, the user uploads another image named “DSC_005.jpg” and again checks the URL which turns out to be same because it’s programmed to renamed. So the user can figure out URL of any of his uploaded profile picture and he will now try to upload a shell file (it’s like a backdoor access to servers; somewhat like a cPanel within a PHP file). Shell files end with ‘.php’ extension and since we aren’t checking for the extension of files, this will get uploaded to “../image/id_87.php”. The bad guy just needs to visit that address and instead of an image, he’ll get a shady control panel which offers everything to take over your website. He’ll have access to all your files which can even reveal the connection details of your database. So that’s how a single user can steal all other user’s details. To safeguard your website from such attacks, you need to check extension of files being uploaded. Don’t go with excluding specific extensions instead go on by just allowing specific extensions that you expect the user to use, for all the others, just throw up an error. Even by mistake, do not transfer the unwanted file to your server and then throw the error, that’s just stupid but often practiced. Make sure that all these checks are performed server-side because if you are doing it on the user-end then the bad guy can easily dodge the check (hint: Inspect element). Lastly, the least effective advice, use ‘chmod’ and never set any uploaded file’s permission to 777 (that means read, write, execute access to everyone), you must use 644 or whatsoever your application demands.
Validation of requests being made
A few months back, a person found a vulnerability on YouTube. All he did was modifying the POST request, from his own Video ID to the target video’s ID, that allowed him to delete any YouTube video without the uploader’s consent which could have actually created a big mess. Getting back to our dummy website, if the user clicks on ‘delete profile’, a POST request will be generated which can be tampered easily by using plugins such as ‘Tamper data’ or ‘Postman’ (for Firefox and Chrome respectively). This is how the bad guy will proceed: He’ll turn on the plugin, click on Delete Profile on the user dashboard, interfere with the POST request being made using plugin and change the ID from his own to someone else’s ID and then let the request proceed. And as you might have guessed, someone else’s account will get deleted without that user’s consent.
This is why it’s extremely important to verify whether the action being executed is legitimately initiated or not. To overcome such requests, you’d need to implement Cross Site Request Forgery (CSRF). When the user logs in, generate some random values and stick it up to the user’s session and have a copy of it on the server side too. For every requests, insert this random value in the POST data (use hidden field for forms) and cross-check this value, whether it matches with the one stored on server side or not. If it doesn’t, simply return an error, and that’s how you made your whole environment more secure.
You probably heard this term earlier is your website safe from SQL Injections? This is probably the least effort consuming way of hacking into any poorly coded website and of course, tons of websites (especially small businesses’) are vulnerable to SQL injection. Imagine you are on the login page of our dummy website, a normal user will input his username and the password for it, and if they match, the user will be logged in. However, what if instead of a normal user, a bad guy comes up and he inputs some cryptic strings, guess what, he will get logged into the first account that’s present in the database, which generally is of an administrator.
What actually happened over here is that the cryptic string altered the behaviour of your SQL commands. In any code, ‘terminators’ play important role and that cryptic string, consisting of numbers and conditions, basically tricked the program. So, if our MySQL query was something like:
SELECT id FROM users WHERE username = $username AND password = $pwd;
And the bad guy puts username as “1 OR 1 = 1; --” and submits the form. This will actually convert our MySQL statement to
SELECT id FROM users WHERE username = 1 OR 1 = 1; -- AND password = any_random_text;
Which will get the user logged into someone’s account without even knowing the password. (Double dashes above stands for comment in SQL).
To overcome such vulnerabilities, you should use “mysql_real_escape_string()” function (for PHP version < 5.0) or start using ‘mysqli’ (for PHP version >5.0). Both of them will filter out the unwanted characters and no longer the bad guy could exploit your site.
With those three practises you have actually made your website much more secure and are assured to keep script kiddies at bay. And wait, there still lies a lot of undiscovered vulnerabilities that keep popping out every day thus making none of the systems secure enough. So keep an eye on the news and efficiently improve your code wherever possible.
Disclaimer: The above topic is purely for educational purposes. Do keep in mind that you are fiddling with the website’s coding and any erroneous code can render your website dysfunctional. A first hand experience of writing code and building a website is essential. Digit and its parent company are not legally responsible for any outcome that may arise out of the implementation of the above article in any and all ways.
Note: This article has been contributed by a member of Digit Squad.
This article was first published in July 2016 issue of Digit magazine. To read Digit's articles first, subscribe here or download the Digit e-magazine app for Android and iOS. You could also buy Digit's previous issues here.