Security and the Average Joe

by Mike Willbanks on February 21st, 2006

What is funny about Security is the lack of knowledge among most developers. In a project that I had I was securing an ASP website that shows this lack of knowledge. While there are items to check for what type of data there is, most just grab from a request variable and insert it directly into a SQL statement. This not only causes SQL Injection and Loss of Data (depending on permissions) it is just downright laziness. There is information everywhere on these types of issues. And is also featured on the OWASP Top 10 vulnerabilities, of which, I believe there was all but 2 of the issues present in that project.
Here are the 3 most common I have been running into so far on this project:

  • Unvalidated Input
  • SQL Injection
  • XSS Flaws

I will try and give a brief overview of these 3 items and how they are harmful using some PHP and MySQL reasoning since that is what most people in the PHP world are running.

Unvalidated Input

When you are coding an application, you normally need to pass information both in and out to different files (or to the same one). This information ends up in foreign territory where it can be used and abused. If we are expecting an integer we better make sure it is an integer. Just about every vulnerability where an applications security is violated it can be attributed to unvalidated input, input that wasn’t quite validated correctly or improper escaping of the data.

One of the most common things that I see is the simple remote inclusion and local file vulnerabilities:


So lets take a little while to explain why that is a vulnerability… You can prefix files with basically everything you want however it is simple to forge the request to make it include files that you are not even looking for. One simple thing is to add a null character in the url string. What this does is eliminate everything you put on the end of the file. Take the following code for instance:


Now what that will do is include that remote file if magic_quotes_gpc is off (which it should be), and allow fopen url is on. Now this vulnerability is extremely bad because they can execute any code they would like on the box that you are currently running. This means deletion of files an open spam gateway, etc… This is very simple to prevent against but most people do not take the time to understand why it should be implemented. I typically take the whitelist approach by manually entering in the files, although you can do a search on a directory and store that information into a new file (we will not do this today).

//example one:
$allowed_pages = array('file_one', 'file_two', 'file_three');
if (!in_array($_GET['file'], $allowed_pages) {
//example two
switch ($_GET['page']) {
case 'file_one'
case 'file_two'
case 'file_three'

I think that example was straight forward enough however there are other types of things to prevent against, like always checking to make sure that the data is valid to show and present. But we will cover some more of that information in a little bit here.
SQL Injection

$id = $_GET['id'];
$query = "SELECT * FROM category WHERE id=$id";

Now to me this is obvious but you can spot the problem by looking at how the $id is is passed directly into the variable and then directly into the SQL statement. Not only is this just a problem with invalid input but you can modify the SQL statement by passing the id anything you would like in the browser query string. Also if you use single quotes around the ‘id’, do not think you are protected as you can pass a single quote through the query string as well.

What this code should look like is more of the following nature:

if (!$id = (int) $_GET['id']) {
exit('Thought you could trick me ey?');
$query = "SELECT * FROM category WHERE id='$id'";

What we did here was type cast the id to an integer, if it was not an integer we halt the application. If you pass a string to the id without any leading numbers it will cast it to the integer to 0. This will evaluate to false and exit the process. However if the integer is positive we will run the query. Note that you could have used is_numeric() but type casting is much faster as it requires no function call and makes it our expected input.

XSS Flaws

XSS is one of the most common flaws in applications and it is hard to say why when the functionality is provided right in PHP to prevent against this simple minded attack. XSS basically allows someone to insert HTML on a page and most of the time involves JavaScript.

Take for instance the following scenario: You have a community site where you allow users to post changes to their pages via HTML. They are able to incorporate some type of JavaScript that utilizes an AJAX response to delete the logged in users account when they hit your page.

What can be done about this? The simplest thing is to remove all HTML capabilities. The second is to allow certain tags but get rid of certain attributes. However getting rid of certain attributes is much harder and more prone to errors.

//getting rid of all HTML and showing entities instead
echo htmlspecialchars($user_inputted_string);
echo htmlentities($user_inputted_string);

I will explain some more later and try to show a function to strip out everything not in a white list of defined elements!

From PHP

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS