Basic PHP Security

1 Reply • Leave your reply

Introduction

PHP is the most common server-side programming language, but this popularity has also made it the target of many different kinds of security attacks. Learn best practices for new PHP users to secure your PHP installation and scripts.

Requirements

  • A Cloud Server with PHP installed and running.

Note: PHP is installed and running on a Standard Linux installation by default. If your server was created with a Minimal installation, you will need to install and configure PHP before you proceed.

Update PHP Regularly

It is a good practice to update your PHP installation regularly, in order to get the latest security fixes and patches. The following commands will update the packages installed on a server, including all of the various PHP packages:

  • CentOS 7: sudo yum update
  • Ubuntu 16.04: sudo apt-get-update

Handling Input and Output

Whenever PHP is accepting input from a web page, and particularly when it is accepting user-submitted data, this poses a security risk. Unless a few basic steps are taking to "sanitize" the data, it is trivially easy to hijack these scripts.

Check Data Types

Whenever possible, always check to make sure that the input is the correct type of data.

For example, this POST function is used to send PHP a page number:

$nextpage=$_POST['page_id'];

Since we know that page_id should always be an integer, it is best to verify this first, using the is_int() function:

if (is_int( $_POST[ ‘page_ID’ ])) {
  $nextpage=$_POST['page_id'];
} else {
      echo "Error: The page ID is not a valid number.";
    }

Limit Variable Length

Whenever a script accepts external input, you should limit the number of characters that the script will accept. Otherwise, the server will be vulnerable to a buffer overflow attack.

You can check the length of a string with the strlen() function. This example checks to make sure that the username field has a maximum of 64 characters:

if (strlen($_POST[‘username’]) <= 64) {
  $username=$_POST['username'];
} else {
      echo "Error: Usernames cannot be more than 64 characters long.";
    }

Use strip_tags to Remove HTML

Never accept HTML in a form where it wasn't intended, as this is a common way of performing an attack. If a field should not contain HTML, use strip_tags to remove any HTML as a precautionary measure.

This example uses strip_tags to remove HTML from a username field:

$username = strip_tags($_POST[‘username’]);

Escape the Output

Whenever PHP passes data to MySQL or HTML, that data should always be "escaped." This means that it will be flagged by the destination as potentially harmful, thus no code will be executed.

HTML

Whenever a PHP variable is embedded in HTML, it should be escaped with htmlspecialchars first. This will prevent Cross-Site Scripting (XSS) attacks.

For example, to echo the PHP variable $username on an HTML page:

$username = htmlspecialchars($username);
echo $username; 

MySQL/MariaDB

Another common use case is inserting PHP data into a MySQL/MariaDB database. For example, to insert the $username variable into a database:

$username = $mysqli->real_escape_string($username);

$query = "INSERT INTO account (username) VALUES ('$username')";

Avoid Using Risky PHP Functions

Whenever possible, avoid using the following functions when writing a PHP script:

  • shell_exec
  • popen
  • exec
  • passthru
  • system
  • pcntl_exec
  • backtick operator ```
  • eval()

All of these functions are considered risky, because they will run the strings which they accept. This makes them vulnerable to code injection attacks.

Prevent Session Hijacking

PHP's default session handling functions have fairly robust security as a default. However, there are a few measures you can take to ensure that your users' sessions will not be hijacked.

Bind Sessions to the User's IP Address

As a general practice, whenever you are collecting and using session data, it is a good idea to bind this data to the user's IP address. This can help prevent session hijacking.

The getenv() function can return the user's IP address, which you can then store along with the session data:

$IP = getenv("REMOTE_ADDR");

Change the Session ID

Whenever a user's elevation is changed, the session ID should be changed as well. For example, when a user logs in, or a logged-in user authenticates as an admin, the session ID should change.

Inactivity Timeout

A user's session should expire after a specified time since their last action. 30 minutes to an hour is considered a standard amount for an inactivity timeout.

This will not only prevent session hijacking, it will also protect your users if they forget to log out while using a public computer.

You should also always provide a Log Out button, and unset the session when the user logs out.