PHP Security
What Is PHP?
PHP is a programming language that is primarily used for web development. You can use it to create dynamic websites and embed it into HTML. PHP stands for Hypertext Preprocessor and is a server-side language, which means that the code is executed on the server rather than in the user’s web browser.
PHP is important because it is a widely-used language for creating dynamic websites. It is used by many popular websites and content management systems, such as WordPress, Drupal, and Joomla. PHP is also relatively easy to learn and use, compared to other programming languages, which makes it a good choice for web developers who are just starting out.
Because of PHP’s popularity, it is a valuable target for cybercriminals. Common security vulnerabilities affecting PHP applications include SQL injection, cross site scripting (CSS), and cross-site request forgery (CSRF). Owners of PHP websites can protect against these attacks via best practices like upgrading their PHP version, using the secure HTTPS protocol, and leveraging prepared SQL statements to prevent injection.
This is part of a series of articles about application security.
In this article:
- PHP Security Issues and Vulnerabilities
- SQL Injection
- XSS (Cross-Site Scripting)
- Cross-Site Request Forgery (CSRF)
- Session and Cookie Hijacking
- Buffer Overflows
- Source Code Exposure
- 6 PHP Security Best Practices
- Update Your PHP Version Regularly
- Use SSL Certificates For HTTPS
- Log all Errors and Don’t Display them in Production
- Use Prepared SQL Statements
- Always Validate User Input
- Use URL Encoding
PHP Security Issues and Vulnerabilities
SQL Injection
SQL injection is possibly the most common attack on PHP applications. It works by tricking server-side code into pushing malicious SQL commands to the database. These SQL queries can return information that the original web application developer does not want to expose – including the entire contents of the database, personal information, passwords, etc. In other cases, malicious queries can be used to compromise the database or the host system.
For example, the following query below uses unsanitized user input directly in the SQL query:
// Create the SQL
$sql = "SELECT * FROM 'users' WHERE 'id'=”’” . mysql_escape_stgring($_GET[id]) . "’”;
// Execute the query
$users = mysql_query($sql);
This allows a hacker to break the statement and query additional information, including any user’s data.
XSS (Cross-Site Scripting)
Cross Site Scripting (XSS) allows attackers to execute malicious JavaScript on websites to perform harmful actions against website users. This typically works by injecting client-side script code alongside legitimate content. When an unsuspecting user tries to visit the website, the code runs in the user’s browser and might be used to hijack their session, download malware, or redirect the user to a malicious website.
Cross-Site Request Forgery (CSRF)
Cross-Site Request Forgery (CSRF) attacks force end users to execute undesirable actions on a web app in which they are authenticated. By using social engineering techniques, such as sending malicious links in an email, attackers can trick users of a target application into executing malicious scripts.
If a CSRF attack successfully targets normal users, it can force them to perform requests that change the application state, such as transferring funds or changing their email addresses. If the attack targets an administrative account, it can compromise the whole web application.
Session and Cookie Hijacking
Cookies are files that store user credentials and help users maintain a session even after they leave a website. This means that if a hacker steals a user’s cookie, they can log into their account without credentials.
Websites that handle PHP sessions tend to store session data on the web server. However, when the browser sends a session identifier as a cookie, attackers can intercept this and use it to impersonate the user.
Buffer Overflows
A buffer overflow is a common programming error in the C and C++ programming languages. PHP code cannot directly cause a buffer overflow, but C code in the PHP engine can result in buffer overflow. This means many PHP systems are vulnerable to this attack.
A buffer is a memory storage region that temporarily holds data while it is being transferred between different locations. A buffer overflow (or overrun) occurs when the data volume exceeds the memory buffer’s storage capacity. As a result, a program trying to write data to the buffer will overwrite adjacent memory storage locations.
Source Code Exposure
PHP is a server-side language. Just like server-side scripts, the source code of the code is not intended to be shared with users. For example, if you request the source of a .php extension file, the server will execute the PHP code contained in the file and return the resulting HTML to the user, meaning that third parties should not have access to the PHP scripts.
However, if the server is misconfigured, it will return the script in plain text and indicate their origin. Some of these scripts are highly exploitable because they are likely to contain sensitive information like database credentials and configuration file details.
6 PHP Security Best Practices
Update Your PHP Version Regularly
It is important to use an up-to-date PHP version, as new versions usually contain patches for newly discovered security issues. Failure to update to the latest stable version could allows hackers to exploit known vulnerabilities.
PHP provides preview builds of newer versions, but it is usually not a good idea to participate in preview testing, because preview releases might contain unknown security vulnerabilities.
Use SSL Certificates For HTTPS
All modern browsers such as Google Chrome, Opera and Firefox recommend using the HTTPS protocol for web applications. HTTPS provides a secure, encrypted channel to access websites. It also hardens web applications against XSS attacks and prevents hackers from intercepting transmitted data (known as man in the middle attacks).
To support HTTPS, your PHP website must have an SSL certificate installed and redirect all traffic from HTTP to HTTPS, to avoid any traffic flowing over an insecure HTTP channel.
Log all Errors and Don’t Display them in Production
After you develop a PHP website and deploy it to a live server, the first thing you should do is disable error display, as hackers can retrieve valuable information from errors. Set the following parameter in your php.ini file:
display_errors=Off
However, make sure that errors are logged and saved to a secure location for later use. The file path below is just an example.
log_errors=On
error_log=/var/log/httpd/php_scripts_error.log
Use Prepared SQL Statements
Inserting user input directly into a SQL statement is a common mistake. It leaves the door open for SQL injection attacks because the user can subvert intended SQL queries and execute arbitrary queries.
Prepared statements are a database feature that ensures queries are built on the server side, without directly using user inputs to structure the query. This can prevent most SQL injection attacks.
Here is what the prepared statement code looks like:
$stmt = $conn->prepare("INSERT INTO users (firstname, lastname) VALUES (?, ?)");
$stmt->bind_param("ss", $firstname, $lastname);
The bind_param
function specifies the type of data that the SQL query should pass, ensuring that parameters inside the query are of type String. This is a strong security measure that validates input data.
Always Validate User Input
In addition to prepared statements, a secondary security measure is to validate any user input accepted by the application, to ensure that all data is of the correct type and format. It is important to validate data type, length, and format of user input, and reject inputs that don’t match expected conventions. If possible, use an allowlist of expected values, and validate the input data only if it matches one of the allowed values.
Use URL Encoding
PHP provides developers with the urlencode
function to safely construct valid URLs. According to PHP documentation, this function can be used to encode a string used in the query part of a URL.
In general, it is not advised to include user inputs in URLs. However, because in practice this is sometimes done, it is critical to encode all dynamically generated URLs to ensure malicious inputs are automatically converted to strings.