Common Security Issues in PHP and How to Prevent Them
PHP is a popular language for building websites, but it has some security problems that developers need to be aware of. Over the years, I’ve dealt with many of these issues and found ways to prevent them. In this blog post, I’ll share my experiences and simple solutions to common PHP security problems.
1. SQL Injection
What is SQL Injection?
SQL Injection happens when someone inserts harmful SQL code into a query, which can be run by the database. This can let attackers access, change, or delete data without permission.
How to Prevent It
- Use Prepared Statements: Instead of putting user input directly into SQL queries, use prepared statements with parameters.
- Use PDO or MySQLi: These PHP extensions support prepared statements and are safer than the older
mysql_query
.
// Unsafe query $username = $_POST['username']; $query = "SELECT * FROM users WHERE username = '$username'";
// Safe query using prepared statements $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username"); $stmt->execute(['username' => $_POST['username']]);
2. Cross-Site Scripting (XSS)
What is XSS?
XSS attacks happen when an attacker adds harmful scripts into webpages seen by other users. This can be used to steal cookies, change the website’s content, or redirect users to bad sites.
How to Prevent It
- Escape Output: Use functions like
htmlspecialchars()
to change HTML characters in user inputs before showing them. - Use Content Security Policy (CSP): Set up CSP headers to control where scripts can be loaded from.
Example
// Unsafe output echo $_POST['username'];
// Safe output echo htmlspecialchars($_POST['username'], ENT_QUOTES, 'UTF-8');
3. Cross-Site Request Forgery (CSRF)
What is CSRF?
CSRF attacks make users do things they don’t want to do on a web application, like submitting forms or clicking buttons.
How to Prevent It
- Use CSRF Tokens: Include a unique token in forms and check it on the server before processing the request.
- Use SameSite Cookies: Set cookies with the
SameSite
attribute to stop them from being sent with requests from other sites.
Example
// Generate CSRF token $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); // Include token in form echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">'; // Check token on form submission if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) { die("CSRF validation failed"); }
4. Remote Code Execution (RCE)
What is RCE?
RCE lets attackers run any code on the server. This can be very dangerous, as they can take over the server.
How to Prevent It
- Disable Dangerous Functions: Turn off functions like
eval()
,exec()
,shell_exec()
,system()
, andpassthru()
inphp.ini
. - Validate and Sanitize Input: Check all user inputs and remove any harmful content to stop malicious code from running.
Example
; Disable dangerous functions in php.ini disable_functions = exec, shell_exec, system, passthru
5. File Inclusion Vulnerabilities
What are File Inclusion Vulnerabilities?
These happen when attackers can include and run files on the server without permission.
How to Prevent It
- Use Absolute Paths: Always use full paths instead of relative ones when including files.
- Validate File Paths: Check and clean file paths, and don’t use user inputs directly in file paths.
Example
// Unsafe file inclusion include $_GET['page']; // Safe file inclusion $allowed_pages = ['home', 'about', 'contact']; $page = in_array($_GET['page'], $allowed_pages) ? $_GET['page'] : 'home'; include "/var/www/html/pages/{$page}.php"; Keeping your PHP applications secure takes effort, but it’s worth it. By using prepared statements, escaping output, checking inputs, and adding security headers and tokens, you can prevent many common security problems. Stay informed and keep learning about security best practices to protect your applications.