CyberArmy University | Open Source Institute | CyberArmy Intelligence & Security | CyberArmy Services & Projects

[Library Index]

[View category: PHP] [Discuss Article]

Website Security with PHP: Avoiding Injections

Article is yet to be rated
Author:      Urthogie
Submitted:      01-Jan-1970 01:00:00
Imported From:      zZine (original author: Urthogie)


The most common security vulnerability I run into when auditing web sites is the lack of security measures against HTML, code, and database injections. In this article I'll go over all three forms of injection, providing examples of each one.
HTML Injection

The goal of HTML injection(also known as cross-site scripting), is to inject HTML or Javascript in places where the script does not intend it to be. This vulnerability is seen often on guestbooks. It can go as far as the attacker collecting cookie credentials on the target site's visitors, so it is definitely a significant security threat. The following is an example of a vulnerable guestbook, in which the users submit their comments to a file, which is then read.

Guestbook.php
<?php
$comments=$HTTP_POST_VARS['comments'];
$file='comments.txt'
//assign shorter names to variables 
if ($comments) {
   //if they submitted comments...
   if (is_writable($file)) {
      //if its possible to write to the file
     @$handle=fopen($file,'a');
     //create a file handle, for appending comments.txt
     @fwrite($handle,$comments);
      fclose($handle);
     //write the comments to comments.txt, then close up the file operation.
   }
   echo("<h2>Guestbook Comments</h2><hr>");
   @$handle=fopen($file,'r');
   $allcomments=fread($handle,filesize($file);
   fclose($handle);
   //open up comments.txt for reading, read from it, then close it.
   echo("$allcomments");
   //display all the comments
}
else {
//display the comment form
?>
<form action="guestbook.php" method="post">
Comments: <input type="text" name="comments"><br>
<input type="submit" value="Comment on Guestbook">
</form>
<?php
}
?>
The problem with this script is that it allows HTML to be injected through the comments field. Because there are no protective measure against injection, an attacker can inject HTML that all viewers of the guestbook will now be exposed to.

Code Injection

In code injection, an attacker aims to execute commands that are uninvited by the script. The implications of a code injection vulnerability are almost always very serious; half the time I see code injection translating into the attacker being able to execute commands, with the permission levels of the web server. In addition, I've seen entire web sites hacked solely with the use of code injection. While HTML injection usually aims to hack the website's viewers, code injection almost always attempts to hack the web site itself. Take the following example of a script which executes the Unix ls command on a user supplied filename:

list.php
<?php
$file=HTTP_POST_VARS['file'];
//shorten variable names
if($file) {
   //if a file name was submitted through the form...
   echo("<h2>Results of command:</h2><hr>");
   $result=shell_exec("ls -l $file");
   echo("$result");
   //display the result of the complete system command
}
else {
   //if they're yet to submit the form, display the form to them:
   ?>
   <form action="list.php" method="post">
   Filename to list: <input type="text" name="file"><br>
   <input type="submit" value="execute command">
   </form>
<?php
}
?>
The problem with this script is it allows an attacker to execute multiple commands. For example, if we input the following:

foobar; cat /etc/passwd

We end up executing two commands: 1) list the file foobar and 2) display the contents of the password file! Because there are no protective measures against code injection, the attacker is able to execute any system command they desire, at the level of the webserver. It goes without saying that from here, there is a good chance the attacker could get to root.

Database injection

The aim of database injection is to take advantage of the mechanism by which the script accesses the database. Successful injection often results in getting in the website without the password, or worse. Take for example the following vulnerable script:

logincheck.php
<?php
$user=$HTTP_POST_VARS['user'];
$pass=$HTTP_POST_VARS['pass'];
//assign shorter variable names
if ($user) {
   //if username has been submitted...
   $check = mysql_query( SELECT Username, Password FROM Users 
WHERE Username =     ' .$_POST['username']. '
 and Password = ' .$_POST['password']. ' );
   //check if they used proper username and password
   if ($check) {
      //if they used a proper login...
      $HTTP_SESSION_VARS['logged_in']=$user;
      Echo("You are now logged in. Proceed to <a href="members.php">members</a>.");
      //set them as logged in and tell them
     }
   else {
      //if it was an incorrect login...
      Echo("Incorrect username and/or password.<a href="logincheck.php">Try again</a>.");
   }
}
else {
   //if they are yet to submit a login...
   ?>
<form action="logincheck.php" method="post">
<input type="text" name="user"><br>
<input type="password" name="pass"><br>
<input type="submit" value="login">
<?php
} 
?>
The problem is that it is possible to inject SQL into the script input. Because there are no protective measures, the script could be exploited by submitting the following username along with a blank password:

' OR 1=1 #

By inputting that string, the query becomes:

SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''

This works because the hash symbol(#) tells MySQL to ignore anything following it, and view it as a comment. Because 1 always equals 1, all of the usernames and passwords in the database will be selected and returned to the attacker. All of this could have been prevented with some protective measures.

Preventing Injections with PHP Functions

We have many PHP functions at our fingertips which can help us prevent all of the injection examples highlighted in this article:

htmlspecialchars()- The string that this function is performed on is displayed as if it is regular text instead of HTML. Therefore, it can prevent HTML injection.

escapeshellarg()- This sets up a string to be used as a command argument, so no special characters can be used to manipulate the system call from the script. Therefore, it can prevent system command injection(a form of code injection).

mysql_escape_string()- This sets up a string to be used in a MySQL query. Therefore, it can prevent MySQL injection.

addslashes()- This adds slashes to special characters, making them uninjectable. Therefore, it is useful in preventing many injections. (Sidenote: when actually displaying the data, you'll often want to remove the slashes with the stripslashes() function.)

Conclusion

Remember to use built in functions to insure against the injections highlighted here. Remember, it only takes one function most of the time to prevent injections. If you have any questions you can ask me any time on IRC or CMS.

This article was originally published by CyberArmy.net in the CyberArmy Library.

You must be logged in to vote on an article

About Us | Privacy Policy | Mission Statement | Help