PHP is an open source scripting language, there are so many features available in PHP that can lead security problems, like as we know there is no requirement to declare the variable data type in PHP.
Error reporting in PHP
Error reporting is a process that is helpful to get useful information whenever an application fails. It provides the complete information regarding what happened and where the problem occurred? Obviously, if the developer could not get this information bugs cannot be fixed. In the development environment it is preferred to display errors, so that developer can fix those errors.
But this information is useful only for the developer not for the user. So, we have to handle this error reporting process and never display the details to the user and not allowing them to trace how the application is working. In other words error reporting is not preferred in a production environment.
PHP applications insert all errors into a log file on the server by default. For all these tasks, some directives need to be set in pnp.ini file:
Such as:
- display_errors: It controls whether the error messaged should be displayed on screen or not? In a production environment, it should be turned off.
- error_reporting: It controls about which errors should be reported. We can set it as E_ALL, so that all errors can be fixed.
- log_errors: It controls about whether the errors should be logged in a file or not. It should be turned ON.
- error_log: It is used to set the path of the file where the errors should be logged. It can be applied if the log_errors is turned ON.
SQL Injections in PHP
It is a type of web application security vulnerability, in which an attacker can execute SQL command and it is executed by the web application. The main cause of this type of attack is that a web application can accept user data without proper validation. SQL injections can be used to create, read, update, alter or delete data from database.
Let’s assume the following line of code which is used to validate the username and password in most web applications:
$verify=mysql_query(“SELECT usrname,passwd from userdetails WHERE usrname=’’.$_POST[‘username’].”’ And passwd=’”.$_POST[‘password’].”’)
This line of code can be easily made harmful by using SQL injections like
If we enter this username and password in the form:
‘ OR 1=1 #
Then query will be interpreted in a totally different way
Such as:
SELECT usrname, passwd from userdetails where usrname=’ ’ OR 1=1# and password=’ ’
Here # symbol will make the complete database accessible to the user because it will pass wrong meaning to mysql that after # symbol everything should be ignored.
We can save our database by applying some security tips to our PHP code. Like we should use make_safe() function in the following way to secure username and password.
function make_safe($var)
{
$var=mysql_real_escape_string(trim($var));
return $var;
}
Now we can use make_safe() function in the following way to access username and password:
$usrname=make_safe($_POST[‘username’]);
$passwd=make_safe($_POST[‘password’]);
$verify=mysql_query(“SELECT usrname,passwd from userdetails where usrname=’”.$usrname.”’ And passwd=’”.$passwd”’”);
Now this code is completely harmless and nobody can access this.
Site defacement
This type of attack is specially used by crackers. For example In the following code when the user enters his/her name, this script read that from form and stores it in a text file, other users can see the input.
Example: security.html
<html> <head> </head> <body> <h1> visitors to this site:</h1> <ol> <?php $fp=fopen("database.txt","r"); while(!feof($fp)) { $line=fgets($fp,4096); echo $line; } fclose($fp); ?> </ol> <HR> <form method=POST action="security.php"> <input type="text" name="visitor"> <input type="submit" name="submit" value="Sign In"> </form> </body> </html>
Security.php
<?php error_reporting(0); if(isset($_POST['visitor'])) { $visitor=$_POST['visitor']; $fp=fopen("database.txt","a"); fwrite($fp,$visitor); fwrrite("\n"); fclose($fp); } ?>
Output of above code:
When visitors access this page, the browser receives tags and immediately begins hacking site. PHP provides a way to perform such type of translation in which special characters like <,>,” etc. will convert in HTML entities. htmlspecialchars() is one of them, so if we use following code, then other users can easily access prior visitors of this site.
<?php error_reporting(0); if(isset($_POST['visitor'])) { $visitor=$_POST['visitor']; $fp=fopen("database.txt","a"); $clean_visitor=htmlspecialchars($visitor); fwrite($fp,"<li>$visitor\n"); fclose($fp); } ?> <html> <head></head> <body> <h1> visitors to this site:</h1> <ol> <?php $fp=fopen("database.txt","r"); print(fread($fp,filesize("database.txt"))); fclose($fp) ?> </ol> <HR> <form> <input type="text" name="visitor"> <input type="submit" name="submit" value="Sign In"> </form> </body> </html>
Output:
Use of global variables in PHP
In PHP we can use global variables by applying simple setting register_globals option in php.ini file. But if allowed global variables and server has register_globals option set to on, then simply adding some content in URL will give any chances to access information that should not be displayed. To secure this we should set register_globals to off.
File manipulation
In web applications if URL is used like this:
index.php?page=contactus.html
User can easily access the contactus.html page and also can modify this.
A user can also modify URL like this in this case as:
Index.php?page=.htpasswd
To secure web site from this type of security threat we should make sure that open_basedir setting should be correctly done in php.ini file and allow_url_fopen should be off. It will prevent these types of attacks.
Not using default username and password
In PHP, mysql is mostly used database and its default username is root and the default password is blank. In most of the cases this default password should be changed to secure the database from malicious users.
Configuration files
While deploying PHP sites, it is recommended that configuration files must be stored in file systems, where nobody can access these files. If we store configuration files into the root document with the extension.php, it will not be displayed as plain text. Apart from these security features we should also apply encryption in configuration files.
Setting for production environment
To hide errors in a production environment, we must configure php.ini file as:
display_errors=off
display_startup_errors=off
error_reporting=E_ALL
log_errors=On
Protect PHP code against XSS attacks
XSS attack is also known as cross site scripting attack. This type of attack is based on code injection, resulting in accepting unchecked input data and also display it in the browser.
It can be explained like if there is a form, in which a user can enter data in the form of comments. The user can enter some dangerous javascript code also in this type of form and when the form is submitted, the data is sent to the server and stored in the database. When some other user fetches this information from the database, the javascript code will execute and generate malicious result. To protect this type of attack, run code in strip_tags() and also apply htmlentities() function on the data.
Protecting PHP code against CSRF attacks
It is also known as cross site request forgery attacks. In this type of attack sensitive information can be displayed and malicious transactions can be made without any authorization. These types of attacks are mainly implemented through GET requests.
For eg:
<? php
if (isset($_REQUEST[‘name’],$_REQUEST[‘amount’]))
{
//code to process the request
}
If the above code request is received and processed using GET method, then a user can use following type of link to pass information:
<a href=”http://example.com/process.php?name=JohnSmith&amount=5000”> Click Me </a>
If a user clicks on this link by mistake, it can produce harmful results like: money transfer.
To provide protection against this type of code, we should use POST method whenever information should be passed from HTML form to PHP file and avoid using $_REQUEST to retrieve GET parameters and use $_POST to pass POST parameters.