Securing PHP applications Part I – Securing PHP code

There are a lot of books treating this issue. So, why another post about this subject. Well, here a try to cover this problem in a short way so that you don’t have to read hundreds of pages or to search all over the Internet for this.

These being said, you must know that securing a PHP application is not an easy process, as you may think and involves a lot of other things, not just your code.

The things you must take care when trying to secure a PHP application are:
1. Forms
2. URLs
3. Databases and SQL
4. Sessions and Cookies
5. Files and Includes (including file uploads)
6. Commands
7. Authentication and Authorization
8. Shared hosting

So, we are talking about securing our PHP code, about securing PHP on the server and about securing Apache and MySQL.

Because the discussion about securing PHP code is a little bit longer, I’ve divided it into two parts, the third is about securing Apache and MySQL.

Let’ s start with the PHP code. Here, the attack/attacks could be:
1. Cross- site scripting (XSS)
What is it?
This type of attack is one of the most common and known attacks and reflects a special case of code injection. Is the result of sending unchecked, user- supplied data to a browser. For example, a malicious user can create an account with this username,
claudia_helen
and every time someone clicks this username he will be redirected to this page, where the evil user will get his/her sessionID and use it for his malicious purpose.

Also, your site design might be attacked if a user inserts a HTML portion like this one:

</div>

or

</table>

(closing a container before time) depending on your page HTML.

You have to know that are two types of XSS attacks:
- reflected or non- persistent
- stored or persistent

The reflected XSS attack is the most common type of attack and the easiest for the malicious user, which places a link in a banner or a search result from a search engines and makes the user clicks it. This way he can deliver a virus or a malformed cookie.

The stored XSS attack is the scary one because of its devastating results. This is the case for the example presented above.

How should I protect my application from it?
There are several methods to fight against this attack:
1. establish a pattern for the user input, for example username should have only characters and number between 0 and 9
2. use strip_tags when inserting user input into database for cleaning the code of tags like the one above (see http://www.php.net/manual/en/function.strip-tags.php for more details)
3. use htmlspecialchars() when output user input, which converts all applicable HTML characters to entities (see http://www.php.net/manual/en/function.htmlspecialchars.php for more details)

In other words, filter user input.

2. Malicious file execution, file uploads and filename
OBS: If your application doesn’t need to use the uploading process, is safer to disable the file_uploads directive in php.ini.

What is it?
This attack consists of uploading malicious files. For example, assume that you have an application which allows users to upload photos and videos. A malicious user can upload a photo containing some malicious code or even a virus that will read all your files from the server or a user can send a bad name for a filename, like this “../../etc/passwd”.

How should I protect my application from it?
The solution for the second example is relatively simple: you must validate the filename and then to concatenate the filename with a valid directory for upload (a directory where you intend to allow users to upload – is best to place this directory outside the root and don’t forget to give it the proper permissions).
For the first example you have to do a lot more:
- test the file type (MIME type – for this you must install a PECL extension called “fileinfo”, see http://php.net/manual/en/install.pecl.php for details; this is absolutely necessary because you can NOT trust the user input and the name of the file from the $_FILES super global array is generated by the user)
- test to see if the file is really uploaded, with is_uploaded_file() function
- by default the file is uploaded to tmp directory, so you have to move it to a proper directory; you will do this using the move_uploaded_file() function

Here I have to remind you about another problem concerning files: remote filesystem access. For example you may want to read a file this way: file_get_contents(“http://www.site.com/rss.xml”). Ok, but if someone hacks your application and instead of a rss file he puts somethong like this: file_get_contents(“http://www.site.com/index.php?file=http://hackers.org/rootkit.exe”). The solution for that is to disable allow_url_fopen from php.ini, in other words to disable the capability to access remote files. If you really need this directive enabled you have to separate the process intro two distinct tasks, rather than accessing them directly:
- retrieve data
- process data

and for each of the above tasks you can create an API (a function to filter and validate the URL/filename and the content from that URL) to handle it.

OBS: 1. Another thing you should do is to set the upload_max_filesize and post_max_size directives in php.ini to some reasonable values.
2. If coding using a framework, you can use the framework’s build-in library for uploads. For example, if using CodeIgniter you may use the File Uploading Class (more info here, http://codeigniter.com/user_guide/libraries/file_uploading.html ). If using ZendFramework you may use the Zend_File Class (more info here, http://framework.zend.com/manual/en/zend.file.html ) which provides some of the security checks needed.

Another thing to take care is when using the exec() command with user input, for example. That user input must be filtered and validated to protected the server from command injections. In this case you can use escapeshellcmd() or escapeshellarg(), depending on the context.

3. Insecure direct object reference or simpler, semantic URL attacks
What is it?
This is an attack launched just from the URL. How is that possible? Very simple. You have probably seen a lot of URLs like this: http:///www.example.com/index.php?orderId=10 or http:///www.example.com/view_order/orderId=10 .
In the application, you may have an SQL query like this one:

$sql = “SELECT * 
FROM `orders` 
WHERE id={$_GET[‘orderId’]}”;

or

$sql = “DELETE 
FROM `orders` 
WHERE id={$_GET[‘orderId’]}”;

How should I protect my application from it?
Well, here is relatively easy to prevent this things from happening. The method I use is for example to add a userId verification before query the database for order information. The solution for this type of attack is very connected with the context, but in this cases you have to remember to distinguish proper user information like order, account information, etc.

4. Cross- site request forgeries (CSRF)
What is it?
CSRF is a type of attack that allows the attacker to send arbitrary HTTP requests from the victim. Attention, I said the VICTIM. So, in this case you can not detect the attacker.
For example, an attacker can observe the mechanism through which a user buys himself something from an online shop and sees that the order is processed from a URL like this one: http://www.example.com/buy.php?itemId=1&quantity=34 .
Backward, the developer used an $_REQUEST variable to get user’s order and this is fatale because the attacker can buy every item and in what ever quantity he wants. Actually he can place this link in a src attribute of an image that loads every time a page is visited.

How should I protect my application from it?
Well, in this type of attacks the first thing you should do is to use $_POST instead of $_REQUEST, validate the user and use a token validation system to force the user to use your own forms. Maybe you ask yourself what is the deal with this token system, so I give you an example:

<?php
//you have to generate the token and put it in session
    session_start();
    $token = md5(uniqid(rand(), TRUE));
    $_SESSION['token'] = $token;
?>
    <form action="buy.php" method="POST">
    <input type="hidden" name="token" value="<?php echo $token; ?>" />
    <p> Item:
    <select name="item">
      <option value="1">Lipstick</option>
      <option value="2">Mirror</option>
    </select><br />
    Quantity: <input type="text" name="quantity" /><br />
    <input type="submit" value="Buy" />
    </p>
    </form>

Then, you have to check the token from $_POST and compare it with the one from session:

<?php
    if (isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token']){
      /* Valid Token */
    }
?>

No related posts.

115 Responses to “Securing PHP applications Part I – Securing PHP code”

  1. along with the Holidays presently alone weeks away from me, certainly it’s an incredible reward which avid tourist you will ever have.

  2. Unprejudiced report brings out A couple of fresh new stuff regarding babyliss that not a soul is covering.
    Cheap price cheap adidas jackets Outlet York http://www.exercisephysiology.net/adidas-gold-shoes/cheap-adidas-jackets-93lf.html

  3. Disect bathrooms most times popular one or two gallons between sea water landscape utilazation each and every minute, and are generally cost effective.
    wholesale mac makeup http://barrosalgadosantana.com/mac/All-Cosmetics-Wholesale-Best-Wholesale-Mac-Makeup1211111111111111111115.html

  4. as an example, you can actually suit the interior of motor vehicle equipped with honest guru, Gucci or a Louis Vuitton insignia,

  5. Liam says:

    I’m interested in this position http://www.chase.ie/it-recruitment/ prozac paxil zoloft lexapro This year we celebrate the fifth annual PPR Structured Product Awards. The 13 awards are divided into two, covering the products delivered to market over the past year and the support services that are also essential to the market. All the awards are designed to highlight not just the winners but the strengths and capabilities of the range of providers in this highly innovative market.

  6. The mud may well easily wiped a moisten fiber about robust laminate cabinets,

Leave a Reply