This website uses cookies

Our website, platform and/or any sub domains use cookies to understand how you use our services, and to improve both your experience and our marketing relevance.

📣 Try the fastest hosting platform with pay-as-you-go pricing & 24/7 expert support! MIGRATE NOW →

Ultimate PHP Security Best Practices

Updated on December 8, 2021

11 Min Read
php security guide

Since PHP is the backbone for almost every website, therefore, PHP security shouldn’t be considered negligible at any cost. However, PHP developers have the privilege to avoid common threats like cross-site request forgery, SQL injections, and data tampering. And all this comes in handy with the help of PHP built-in security features that make it easier for developers to protect the website.

PHP is said to be the most powerful server-side language, PHP utilizes 80 percent of the world’s web, with top 10 million domains. For this reason itself, it is to understand that PHP will assist you to protect against attackers.

Securing web applications from all sorts of forged attacking attempts is the ultimate duty of a web developer. You should build your web apps protective enough to have no security issues or loopholes.

PHP is the most used server-side web programming language across the world. Different PHP applications share different parts of their code and scripts with other web applications. In Case the shared piece of code is found detected vulnerable, All the applications using that shared piece of code are put at risk and considered vulnerable.

Nothing as Easy as Deploying PHP Apps on Cloud

With Cloudways, you can have your PHP apps up and running on managed cloud servers in just a few minutes.

PHP is the most criticized scripting language when it comes to security. A major chunk of developers and QA experts think PHP has no robust techniques to secure applications. The verdict has some ground too because PHP is the oldest and widely used language for web app development. But for a long time since PHP 5.6, we haven’t seen any major updates regarding security and hence the language faces some security issues.

How Secure is PHP

PHP is as secure as any other major language.  PHP is as secure as any major server-side language. With the new PHP frameworks and tools introduced over the last few years, it is now easier than ever to manage top-notch security.

If we do a comparison PHP is evenly secured. Rails, Java, Javascript, and other languages, all have had their vulnerabilities over the years. “If you find a language that has not had a vulnerability of some shape or form, You can write secure code in PHP perfectly well.

Security Issues in PHP CMS

Popular CMS like WordPress, Joomla, Magento, and Drupal are built in PHP and according to Sucuri, most of the vulnerabilities in PHP CMS came to light during the year 2017:

  • WordPress security issues rose from 74% in 2016 Q3 to 83% in 2017.
  • Joomla security issues have dropped from 17% in 2016 Q3 to 13.1% in 2017.
  • Magento security issues rose marginally from 6% in Q3 2016 to 6.5% in 2017.
  • Drupal security issues dropped slightly from 2% in Q3 2016 to 1.6% in 2017.

cms infection comparison

The current situation is not good enough, but thanks to open source contributors, who are trying hard to overcome the problems and we have seen some drastic changes in PHP of late. PHP 7.x was launched last year with various updates and fixes. The best thing about PHP 7.x relates to the security upgradations which truly revamped the security protocol of the language.

What This PHP Security Tutorial Contains?

I’ve been working on PHP security and performance issues for a very long time, being highly active in the PHP community asking top developers about the tips and tricks they are using in their live projects. Therefore, the main aim of this PHP security tutorial is to make you aware about the best practices for security in PHP web applications. I will be defining the the following problems and mentioning possible solutions for them.

  • Update PHP Regularly
  • Cross site scripting (XSS)
  • SQL Injection Attacks
  • Cross site request forgery XSRF/CSRF
  • Session Hijacking
  • Hide Files from the Browser
  • Securely Upload Files
  • Use SSL Certificates For HTTPs
  • Deploy PHP Apps on Clouds

Note: please do not consider it as a complete cheat sheet. There must be better ways and more unique solutions developers would be applying on the their applications to make it perfectly secured.

PHP Security Best Practice

While creating a PHP web application, a web engineer should be concerned with security best practices. An insecure web application gives hackers the chance to take valuable data, such as client information or credit card details. In addition, a data breach may have an extreme effect on your organization’s validity and future operations.

Update PHP Regularly

Right now, the most stable and latest version of PHP available is PHP 8. And, we have created an ideal PHP benchmarks for our readers. I recommend that you must update your PHP application to this new one. If you are still using PHP 5.6 or 7 then you will be having a lot of deprecations while upgrading PHP apps. You will also need to update your code and change some functional logics like password hashing etc. There are also some tools available to check the deprecation of your code and help you in migrating those. I have listed some tools below:

  1. PHP Compatibility Checker
  2. PHP MAR
  3. Phan

If you are using PHPStorm then you can use PHP 7 Compatibility Inspection, which will show you which code will cause you issues.

Read More: PHP Hosting on Cloudways

Cross-site scripting (XSS)

Cross site scripting is a type of malicious web attack in which an external script is injected into the website’s code or output. The attacker can send infected code to the end user while browser can not identify it as a trusted script. This attack occurs mostly on the places where user has the ability to input and submit data. The attack can access cookies, sessions and other sensitive information about the browser. Let’s look at the example of a GET request which is sending some data through URL:

URL: http://example.com/search.php?search=<script>alert('test')</script>

$search = $_GET['search'] ?? null;

echo 'Search results for '.$search;

You can figure out this attack by using htmlspecialchars. Also by using ENT_QUOTES, you can escape single and double quotes.

$search = htmlspecialchars($search, ENT_QUOTES, 'UTF-8');

echo 'Search results for '.$search;

Meanwhile, XSS attacks can also execute via attributes, encoded URI schemes and code encoding.

Read More: Prevent XSS in Laravel

SQL Injection Attacks

The SQL injection is the most common attack in PHP scripting. A single query can compromise the whole application. In SQL injection attack, the attacker tries to alter the data you are passing via queries. Suppose you are directly processing user data in SQL queries, and suddenly, an anonymous attacker secretly uses different characters to bypass it. See the below-mentioned SQL query:

$sql = "SELECT * FROM users WHERE username = '" . $username . "';

The $username can contain altered data which can damage the database including deleting the whole database in the blink of an eye. So, what’s the solution? PDO. I recommend that you always use prepared statements. PDO helps you in securing SQL queries.

$id = $_GET['id'] ?? null;

The connection between the database and application is made with the below statement:

$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', 'dbusername', 'dbpassword');

You can select username based on the above ID but wait! Here SQL code ‘GET data’ gets injected in your query. Be careful to avoid such coding and use prepared statements instead:

$sql = "SELECT username, email FROM users WHERE id = ".$id." ;

foreach ($dbh->query($sql) as $row) {

   printf ("%s (%s)\n", $row['username'], $row['email']);

}

Now you can avoid the above SQL injection possibility by using

$sql = "SELECT username, email FROM users WHERE id = :id";

$sth = $dbh->prepare($sql, [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);

$sth->execute([':id' => $id]);

$users = $sth->fetchAll();

Also, a good practice is to use ORM like doctrine or eloquent, as there is the least possibility of injecting SQL queries in them.

Read More: Protect PHP Website From SQL Injection

Cross site request forgery XSRF/CSRF

The CSRF attack is quite different to XSS attacks. In CSRF attack, the end user can perform unwanted actions on the authenticated websites and can transfer malicious commands to the site to execute any undesirable action. CSRF can’t read the request data and mostly targets the state changing request  by sending any link or altered data in HTML tags. It can force the user to perform state changing requests like transferring funds, changing their email addresses etc. Let’s see this URL in which GET requests is sending money to another account:

GET http://bank.com/transfer.do?acct=TIM&amount=100 HTTP/1.1

Now if someone wants to exploit the web application he/she will change the URL with name and amount like this

http://bank.com/transfer.do?acct=Sandy&amount=100000

Now this URL can be sent via email in any file, Image etc and the attacker might ask you to download the

file or click on the image. And as soon as you do that, you instantly end up with sending huge amount of money you never know about.

Session Hijacking

Session hijacking is a particular type of malicious web attack in which the attacker secretly steals the session ID of the user. That session ID is sent to the server where the associated $_SESSION array validates its storage in the stack and grants access to the application. Session hijacking is possible through an XSS attack or when someone gains access to the folder on a server where the session data is stored.

To prevent session hijacking always bind sessions to your IP address to:

$IP = getenv ( "REMOTE_ADDR" );

Watch for it when working on localhost as it doesn’t provide you the exact IP but :::1 or :::127 type values. You should invalidate (unset cookie, unset session storage, remove traces) session quickly whenever a violation occurs and should always try not to expose IDs under any circumstances.

for  cookies, the best practice is to never use serialize data stored in a cookie. Hackers can manipulate cookies easily, resulting in adding variables to your scope. Safely delete the cookies like this:

setcookie ($name, "", 1);

setcookie ($name, false);

unset($_COOKIE[$name]);

The first line of the code ensures that cookie expires in browser, the second line depicts the standard way of removing a cookie (thus you can’t store false in a cookie). The third line removes the cookie from your script.

Read more: Redis Server As A PHP Session Handler

Hide Files from the Browser

If you have used micro-frameworks of PHP, then you must have seen the specific directory structure which ensures the placement of files properly. Frameworks allow to have different files like controllers, models, configuration file(.yaml) etc in that directory, but most of the time browser doesn’t process all the files, yet they are available to see in the browser. To resolve this issue, you must not place your files in the root directory but in a public folder so that they are not accessible all the time in browser. Look at the directory structure of the Slim framework below:

slim directory structure

Securely Upload Files

File uploading is a necessary part of any user data processing application. But remember at some points, files are also used for XSS attacks as I have already explained above in the article. Returning to the basics, always use the POST request in the form and declare the property enctype=”multipart/form-data” in <form> tag. Then validate the file type using finfo class like this:

$finfo = new finfo(FILEINFO_MIME_TYPE);
$fileContents = file_get_contents($_FILES['some_name']['tmp_name']);

$mimeType = $finfo->buffer($fileContents);

Developers can create their own custom and ultra-secure file validation rules, but some frameworks like Laravel, Symfony and codeigniter already have pre-defined methods to validate file types.

Let’s look at another example. The HTML of form should be like this:

<form method="post" enctype="multipart/form-data" action="upload.php">

   File: <input type="file" name="pictures[]" multiple="true">

   <input type="submit">

</form>

And upload.php contains the following code:

foreach ($_FILES['pictures']['error'] as $key => $error) {

   if ($error == UPLOAD_ERR_OK) {

       $tmpName = $_FILES['pictures']['tmp_name'][$key];

       $name = basename($_FILES['pictures']['name'][$key]);

       move_uploaded_file($tmpName, "/var/www/project/uploads/$name");

   }

}

Properly declaring the UPLOAD_ERR and basename() may prevent directory traversal attacks, but few other validations – like file size, file rename and store uploaded files in private location – are also required to strengthen the security of the applications.

Read more: Image and File Upload in PHP

Use SSL Certificates For HTTPS

All the modern browsers like Google Chrome, Opera, Firefox and others, recommend to use HTTPS protocol for web applications. HTTPs provides a secured and encrypted accessing channel for untrusted sites. You must include HTTPS by installing SSL certificate into your website. It also strengthens your web applications against XSS attacks and prevents the hackers to read transported data using codes. Cloudways provides free SSL certificates on one-click which are valid for 90 days and you can easily revoke or renew them with a click. You can follow the guides for setting-up SSL Certificates in your PHP, WordPress, Magento and Drupal applications.

Deploy PHP Apps on Clouds

Hosting is the final and paramount step for any web application, as you always create the project on local PHP servers and deploy them on live servers which offer either shared, cloud or dedicated hosting. I always recommend to use cloud hosting like DigitalOcean, Linode, AWS. They are fast, safe and secure for any kind of website and application. They always provide secured layer to prevent DDOS, Brute force and phishing attacks which are highly detrimental for web applications.

You Might Also Like: Pitfalls of Laravel Shared Hosting for Your Projects

To deploy PHP applications on cloud servers, you must have good Linux skills to create powerful web stacks like LAMP or LEMP, which often costs you time and budget for Linux professionals. Instead, Cloudways managed PHP hosting platform provides you the easy way to deploy servers with Thunderstack within few clicks on the above-mentioned cloud providers. The Thunderstack helps your PHP application to be completely secured from various malicious attacks and guarantees optimized performance.

Read more: Enhanced Cloudways Staging Environment Is Now Available for All Users

Document Root Setup

The document root for PHP applications on any server must be set to var/www/html so that users can access your website via the browser. But in some cases, when you are developing APIs with frameworks like Laravel, Symfony, and Slim, you need to update the webroot to `/public folder.

/public serves the output of application similar to simple PHP website with index.php file. The purpose to set the webroot to var/www/html/public is to hide the sensitive files like .htaccess and .env which contain the environment variables and credentials of database, mail, payment APIs.

Also, frameworks like Laravel, Symfony recommend to not move all of your files to root folder, instead creating a nice directory structure to save related files like view, models and controllers is a more reasonable approach.

Log all Errors and Hide in Production

Once you have developed the website and deployed on live server. The first thing you must do is disable the display of errors, because  hackers might get same valuable information from the errors. Set this parameter in your php.ini file:

display_errors=Off

Now, after making display off, log PHP errors to a specific file for future needs:

log_errors=On

error_log=/var/log/httpd/php_scripts_error.log

Obviously, you can change file name as you want.

You Might Also Like: Simplify Laravel Error Logging with PHP Rollbar Integration

Whitelist Public IP for Mysql

When working with PHP apps you frequently need to setup mysql database in internal scripts as well as in mysql clients. Most clients are used to set up MySQL remote connection which needs the IP address or other hostname provide by hosting server to create connection.

The public IP for the remote Mysql connection must be whitelisted in your hosting server so that an anonymous user can not get access to the database. For instance, on Cloudways you can whitelist IP as:

Now you can connect SQLyog or Mysql workbench to work remotely with database.

Q: How to test PHP security?

A: There are few code scanner tools available in the market that can help you analyse the code quality and security of your PHP applications. PHP Malware Finder (PMF) is one of the top security testing tools that helps to find malicious codes in the files. You can also use RIPS as well, which is a popular code analysis tool that helps to find code vulnerabilities in real-time.

Q: How to ensure PHP database security?

A: To ensure database security, you should always use practices like SQL injection protection, database firewalls, regular data encryptions and similar others.

Q: Which is a secure method to encrypt password in PHP?

A: Md5 is the acronym for Message Process 5, and sha1 is the acronym for Secure Hash Algorithm 1. They are both utilized to encrypt strings. Once a string has been encrypted, it gets repetitive to decode it. Md5 and sha1 are exceptionally useful when storing passwords within the database.

Q: What is a PHP vulnerability?

A: PHP Object Injection is an application-level vulnerability that seems to permit an assailant to perform diverse sorts of noxious assaults, such as Code Injection, SQL Injection, Path Traversal, and Denial of Service.

A DDoS attack compromises multiple computer systems attacks. The usual targets are servers, websites, or other network resources.

This happens when user-supplied input isn’t managed before being passed to the unserialize() PHP function. Since PHP permits object serialization, aggressors may pass ad-hoc serialized strings to a defenceless unserialize() call.

Wrapping Up!

Well, The PHP security best practices is a very vast topic. Developers from around the world tend to develop different use cases to secure web apps. While many companies run different bounty programs to find out security loopholes and vulnerabilities in their applications and thus reward those security experts who point out critical loopholes in the applications. This article cover basic PHP security issues, to help you understand how to secure your PHP projects from different malicious attacks. I’ll also write about few more PHP security tips and tricks in the future as well. Till then you can contribute your thoughts and security practices in the comments section below.

Share your opinion in the comment section. COMMENT NOW

Share This Article

Shahroze Nawaz

Shahroze is a PHP Community Manager at Cloudways - A Managed PHP Hosting Platform. Besides his work life, he loves movies and travelling.

×

Get Our Newsletter
Be the first to get the latest updates and tutorials.

Thankyou for Subscribing Us!

×

Webinar: How to Get 100% Scores on Core Web Vitals

Join Joe Williams & Aleksandar Savkovic on 29th of March, 2021.

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Want to Experience the Cloudways Platform in Its Full Glory?

Take a FREE guided tour of Cloudways and see for yourself how easily you can manage your server & apps on the leading cloud-hosting platform.

Start my tour

CYBER WEEK SAVINGS

  • 0

    Days

  • 0

    Hours

  • 0

    Mints

  • 0

    Sec

GET OFFER

For 4 Months &
40 Free Migrations

For 4 Months &
40 Free Migrations

Upgrade Now