Exhaustive List of PHP Vulnerabilities
Exhaustive Reference of PHP Vulnerability Classes
This article is a comprehensive reference covering every major PHP vulnerability class. Use it as a checklist during web application penetration tests. Each entry links to a dedicated article for deeper technical detail.
Quick Reference Table
| Vulnerability | Severity | Key Sink / Pattern | Impact |
|---|---|---|---|
| SQL Injection | Critical | mysql_query, PDO without prepared statements | Data exfiltration, auth bypass, RCE |
| LFI / RFI | Critical | include($input), require($_GET['page']) | Source disclosure, RCE via log poisoning |
| RCE via eval() | Critical | eval(), assert(), preg_replace /e | Full system compromise |
| Object Deserialization | Critical | unserialize($userInput) | RCE, file write, SSRF via POP chains |
| Command Injection | Critical | system(), exec(), shell_exec() | OS command execution |
| SSRF | High | curl, file_get_contents() with user URL | Internal network access, cloud metadata |
| XSS (Stored/Reflected) | High | echo $_GET['x'] without encoding | Session hijack, credential theft |
| XXE | High | simplexml_load_string() with external entities | File read, SSRF, DoS |
| Type Juggling | High | == with mixed types, strcmp bypass | Auth bypass, logic flaws |
| CSRF | Medium | No token validation on state-changing forms | Unauthorized actions as victim |
| Open Redirect | Medium | header("Location: ".$_GET['url']) | Phishing, token theft |
| Path Traversal | High | file_get_contents($_GET['file']) | Arbitrary file read |
| Session Fixation | Medium | session_id() accepted from user | Session hijack |
| Insecure File Upload | Critical | No MIME/extension validation | Webshell upload → RCE |
| Mass Assignment | High | extract($_POST), $$key = $value | Privilege escalation, data tampering |
SQL Injection (SQLi)
The most prevalent PHP vulnerability. Occurs when user input is concatenated directly into SQL queries without proper sanitization. PHP's old mysql_* functions (deprecated) and misused PDO are the most common culprits.
// VULNERABLE
$id = $_GET['id'];
$result = mysql_query("SELECT * FROM users WHERE id = $id");
// SAFE — prepared statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
Local File Inclusion (LFI) / Remote File Inclusion (RFI)
PHP's include() and require() functions can load files from paths controlled by the user. LFI reads local files; RFI (requires allow_url_include=On) can execute remote PHP files.
// VULNERABLE — classic LFI
$page = $_GET['page'];
include($page . '.php');
// Exploit: ?page=../../../../etc/passwd%00 (null byte, PHP < 5.3.4)
// Exploit: ?page=php://filter/convert.base64-encode/resource=config
Remote Code Execution (RCE)
Multiple PHP functions execute OS commands or evaluate PHP code dynamically. Any user-controlled input reaching these functions leads to RCE.
// Command injection sinks
system("ping " . $_GET['host']); // VULNERABLE
exec("nslookup " . $_POST['domain']); // VULNERABLE
// Code evaluation sinks
eval($_POST['code']); // VULNERABLE
assert($_GET['test']); // VULNERABLE (PHP < 8)
PHP Object Deserialization
When unserialize() processes attacker-controlled data, it can trigger magic methods (__wakeup, __destruct, __toString) on arbitrary classes, enabling Property-Oriented Programming (POP) chains.
// VULNERABLE
$obj = unserialize($_COOKIE['data']);
// Attacker crafts a serialized payload that triggers:
// O:8:"UserData":1:{s:4:"file";s:11:"/etc/passwd";}
Cross-Site Scripting (XSS)
PHP applications that echo user input without proper HTML encoding are vulnerable to XSS. htmlspecialchars() without the right flags or encoding context can still be bypassed.
// VULNERABLE
echo "Hello " . $_GET['name'];
// SAFE
echo "Hello " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
Server-Side Request Forgery (SSRF)
PHP applications using curl, file_get_contents(), or other HTTP clients with user-supplied URLs can be tricked into making requests to internal services.
// VULNERABLE
$url = $_GET['url'];
$data = file_get_contents($url);
// Exploit: ?url=http://169.254.169.254/latest/meta-data/ (AWS metadata)
// Exploit: ?url=file:///etc/passwd
// Exploit: ?url=http://internal-server:8080/admin
Type Juggling
PHP's loose comparison operator == performs type coercion. This enables authentication bypasses and logic flaws especially in PHP 7 and below.
// VULNERABLE auth bypass
if ($_POST['password'] == $hash) { /* login */ }
// Magic hash: if $hash = "0e1234567890"
// and MD5(input) = "0e9876543210"
// then "0e..." == "0e..." → both treated as 0 in scientific notation → TRUE
XML External Entity (XXE)
PHP's XML parsing functions (simplexml_load_string(), DOMDocument) may process external entities if not explicitly disabled, leading to file disclosure or SSRF.
// VULNERABLE
$xml = simplexml_load_string($_POST['xml']);
// Attacker sends:
// <?xml version="1.0"?>
// ]>
// &xxe;
// SAFE — disable external entities
libxml_disable_entity_loader(true);
Insecure File Upload
Accepting file uploads without validating MIME type, extension, and content allows attackers to upload PHP webshells. Even checking the file extension client-side is trivially bypassed.
// VULNERABLE
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
// Attack: upload shell.php → access /uploads/shell.php → RCE
// Double extension bypass: shell.php.jpg → depends on server config
// Null byte: shell.php%00.jpg (PHP < 5.3.4)
Mass Assignment via extract()
Using extract($_POST) or $$key = $value patterns allows attackers to overwrite arbitrary PHP variables, including those controlling authentication state.
// VULNERABLE
extract($_POST); // $_POST['is_admin'] = 1 → $is_admin = 1
// Also dangerous:
foreach ($_GET as $key => $val) {
$$key = $val; // variable variables
}
Pentest Checklist: During a PHP application audit, systematically check each category above. Start with the input sources ($_GET, $_POST, $_COOKIE, $_SERVER['HTTP_*'], file uploads) and trace them to each sink type. Every article in this series covers one category in full depth.