Introduction
Actually, this has been taken from my blog(www.sampctricks.blogspot.com) and I re-updated the article for Go4expert. I am myself newbie to programming but still I have included here what I myself practice. This is just a basic guide to prevent basic flaws in your PHP based web apps.
PHP is the most used web developing language and with the increased use of it, there have been increase in poorly programmed sites which have resulted in number of admin hacks and sometimes even worse, server rooting. So I am going to give you some ideas for writing secure codes for general coding flaws in PHP. Most of the time, the programmers forget to sanitize the user input in their PHP code & hence, the code becomes vulnerable to some of the common exploits like file inclusion vulnerabilities, SQL injection, XSS & others... The programmer should never trust anything that comes from the clients and so (s)he should try to create whitelist for what is allowed to. So this article is going to give some ideas on preventing these simple vulnerabilities from your PHP code...
Article Description
General steps:
Validate every input.
Secure your file system.
Secure your file upload system.
Secure your file download system.
Secure your database connection codes.
Secure/encrypt the data.
Now lets start with basic programming flaws and securing steps.
FILE INCLUSION : File inclusion vulns like RFI(remote) & LFI(local) are exploited by including another file(other than intended by programmer) & this can be very dangerous as hackers can completely ruin the system. Many programmers write the codes like below:
PHP Code:
<?php
$page = $_GET['page'];
if (isset($page)) #checks if the $page variable page is set or not
{
include($page); #includes the page without checking if it is legitimate or not...
}
?>
Also many programmers think that they can patch this vuln with the following snippet(based on real example from one of the Nepali ISPs site)
PHP Code:
<?php
$venpage = $_GET['page'];
$venpage = $venpage . ".php";
if (IsSet($venpage))
{
include($venpage);
}
?>
So let me talk about securing it... There are number of ways to secure it and all are perfect. But, at least for me, the switch is the perfect and simplest method to secure this whole code...
PHP Code:
<?php
$page = $_GET['page'];
if(isset($page)) #check if there's page variable set or not
{
switch($page)
{
case "info":
include("info.php");
break;
case "about":
include("about.php");
break;
default:
include("index.php");
break;
}
}
?>
Another method is:
PHP Code:
<?php
//ERROR_REPORTING(E_ALL);
if (IsSet($_GET['page']))
{
$page=$_GET['page'];
$page=preg_replace('/[^a-z]+/i','',$page); //regular expression
include $page.".php";
}
else
{
echo "No page set";
}
?>
SQL INJECTION(SQLi): SQL injections are one of the most prevalent web vulns in the websites and they can be very harmful especially for the commercial sites. But still many sites still remain vulnerable to the SQL injection. & again the problem is the lack of sanitization of GET/POST or COOKIE variables or any other inputs from users... To avoid SQL injection, you need to be as hard as you can. Don't allow any other data types where you assume to be integer types. Don't allow something that is not what you wanted to be accepted by your code. Be as strict as you can for the datatypes.
Now let me show you the simplest form of the vulnerability.
PHP Code:
<?php
//configurations for mysql connection
$host = "localhost";
$user = "root";
$pass = "w000000t";
$db = "db_shop";
//connecting to mysql
mysql_connect($host, $user, $pass);
mysql_select_db($db);
$uid = $_GET['uid'];
if (isset($uid))
{
$query = mysql_query("SELECT * FROM `profile` WHERE `uid` = $uid");
if ($query)
{
while($profile = mysql_fetch_array($query))
{
//display or do something here
}
}
}
?>
The query runs and runs without any filtering mechanism. A malicious user can hence make damage to the database. So what's the solution for this? Simply, type checking. You won't expect uid to be anything other than integer type. Hence, we will be type casting the $_GET['uid'] as an integer type.
PHP Code:
<?php
//configurations for mysql connection
$host = "localhost";
$user = "root";
$pass = "w000000t";
$db = "db_shop";
//connecting to mysql
mysql_connect($host, $user, $pass);
mysql_select_db($db);
$uid = (Int) $_GET['uid']; //you say that uid must be integer...
if (isset($uid))
{
$query = mysql_query("SELECT * FROM `profile` WHERE `uid` = $uid");
if ($query)
{
while($profile = mysql_fetch_array($query))
{
//display or do something here
}
}
}
?>
Note that the ways for securing other datatypes is different. I would list you some of the functions so that you can use them to secure your site from SQLi.
Functions to secure SQLi:
mysql_real_escape_string()
addslashes()
The above example was just for SELECT query but you need to watch the other queries like INSERT, UPDATE and DELETE because you can't just trust the user inputs. Moreover, it is always better to strip the inputs to the limited number of characters so that you won't mess up with SQL column truncation vulnerability(google if you want to know about it). Also, always use quotes and brackets in the SQL query strings if your database allows(MySQL does allow).
Cross site scripting(XSS): Its the most prevalent web app vulnerabilities which have been detected even in high profile sites like facebook, microsoft, twitter, etc. It also occurs when you don't sanitize the user inputs. Consider the guestbook which does something like below:
PHP Code:
<?php
if (isset($_POST['sbtGuestbook']))
{
$name = $_POST['name'];
$comment = $_POST['comment'];
//insert these things into the database
//now print these infos in the page
echo $name."<br />".$comment;
}
?>
the site is going to display it and as since the HTML tags are not filtered, samar will be alerted in the page. Its just an example. Hackers can redirect users from your site using this exploit by inserting <script>location.replace("http://hackerssite.com.np");</script>
Now let me come to securing it.
PHP Code:
<?php
$name = htmlspecialchars($_POST['name']);
$comment = htmlspecialchars($_POST['comment']);
//insert these things into database
//now print them
echo $name."<br />".$comment;
?>
Since these conversions are made to tags, they do not work as HTML tags and hence prevent XSS. More functions to use while preventing XSS are htmlentities(), strip_tags(), url_encode(), etc. To make 100% XSS proof site, validate everything like $_SERVER variables too. They too can be compromised to XSS the site.
Some critical functions: Here are some of the functions you should be careful with while using in your script.
passthru(), exec(), system(), shell_exec(), file_get_contents(), fopen(), fwrite(), file(), readfile(), popen(), mysql_query(), etc.
Other Extra tips: Security of your server can be enhanced by doing some hardening through PHP.INI file too and coding in better styles.
1) Turn off the register_globals
2) Set error_reporting to 0
3) Use @ sign before the functions that are likely to fail usually. eg: @include($page);
4) Turn off allow_url_fopen in PHP.INI
5) Turn on magic_quotes_gpc in PHP.INI
6) Always encrypt the sensitive information. For eg. use md5() once or twice to hash your password, or use different hash functions like md5(sha1(base64_encode(md5($str))));
That was the article on securing common PHP exploits for the new starters in PHP programming arena. In the next issue, I might write the ways to secure other vulnerabilities in PHP codes such as RCE, XSRF, Session and cookies. Till then, bye and Be safe.
Regards~
Deadly Ghos7
NOTE: Based on PHP 5.2.5
![Deadly Ghos7's Avatar author of Securing basic PHP flaws for newbies [Part 1]](http://i.g4estatic.com/misc/unknown.png)
