Common PHP Security Vulnerabilities and Mitigation Strategies
This article outlines ten common PHP security threats—including SQL injection, XSS, CSRF, LFI, weak password hashing, MITM, command injection, XXE, improper error reporting, and login rate limiting—explaining how each attack works and providing practical mitigation techniques such as prepared statements, input sanitization, CSRF tokens, and HTTPS.
Compared with many other languages, PHP makes it easy for beginners to build websites, but most tutorials ignore security. This article surveys several typical PHP security threats and shows how to defend against them.
1. SQL Injection – Attackers can manipulate a query like:
<?php
$username = $_GET['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
?>By sending ' OR '1'='1 the query returns all rows. Use prepared statements instead:
$username = $_GET['username'];
$query = $pdo->prepare('SELECT * FROM users WHERE username = :username');
$query->execute(['username' => $username]);
$data = $query->fetch();2. XSS (Cross‑Site Scripting) – Echoing user input directly, e.g.
<?php $searchQuery = $_GET['q']; ?>
You searched for:Allows injection of <script>alert(1)</script> . Mitigate by escaping output:
$searchQuery = htmlentities($searchQuery, ENT_QUOTES);Or use a template engine (Twig) that auto‑escapes.
3. CSRF (Cross‑Site Request Forgery) – A simple delete‑account endpoint:
<?php
$confirm = $_GET['confirm'];
if ($confirm === 'yes') { /* delete account */ }
?>Protect by embedding a random token in a hidden form field and verifying it on the server:
<form action="/delete-account.php" method="post">
</form>
$csrf = $_POST['csrf'];
if ($csrf !== $_SESSION['csrf']) { die('Invalid request'); }4. LFI (Local File Inclusion) – Including a file based on user input:
<?php
$page = $_GET['page'];
if (!$page) { $page = 'main.php'; }
include($page);
?>Prevent by whitelisting allowed filenames, stripping dangerous characters, and loading only from a dedicated directory.
5. Inadequate Password Hashing – Using MD5 (with optional salt) is insecure:
<?php
$password = 'cat123';
$salt = random_bytes(20);
$hash = md5($password . $salt);
?>Prefer built‑in functions that handle salting and stretching, e.g.:
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
if (password_verify($password, $hashedPassword)) { echo 'Password is valid!'; }6. MITM (Man‑in‑the‑Middle) Attacks – Use HTTPS, enable HSTS, register the site on hstspreload.org , and consider CAA DNS records to restrict certificate authorities.
7. Command Injection – Directly passing user input to shell_exec :
<?php
$targetIp = $_GET['ip'];
$output = shell_exec("ping -c 5 $targetIp");
?>Sanitize with escapeshellarg :
$targetIp = escapeshellarg($_GET['ip']);
$output = shell_exec("ping -c 5 $targetIp");8. XXE (XML External Entity) – Vulnerable XML parsing can expose local files:
<?xml version="1.0" encoding="ISO-8859-1"?>
]>
&passwd;Disable external entity loading with libxml_disable_entity_loader(true) or equivalent configuration.
9. Improper Error Reporting – In production, hide detailed errors by setting display_errors = Off and logging them instead.
10. Login Rate Limiting – Track failed attempts per user and throttle or block after a threshold, optionally notifying the user via email.
By applying these defensive measures, developers can significantly harden PHP applications against common attacks.
Laravel Tech Community
Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.