PHP Security

Exhaustive List of PHP Vulnerabilities

Youssef
17 May 2026

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 InjectionCriticalmysql_query, PDO without prepared statementsData exfiltration, auth bypass, RCE
LFI / RFICriticalinclude($input), require($_GET['page'])Source disclosure, RCE via log poisoning
RCE via eval()Criticaleval(), assert(), preg_replace /eFull system compromise
Object DeserializationCriticalunserialize($userInput)RCE, file write, SSRF via POP chains
Command InjectionCriticalsystem(), exec(), shell_exec()OS command execution
SSRFHighcurl, file_get_contents() with user URLInternal network access, cloud metadata
XSS (Stored/Reflected)Highecho $_GET['x'] without encodingSession hijack, credential theft
XXEHighsimplexml_load_string() with external entitiesFile read, SSRF, DoS
Type JugglingHigh== with mixed types, strcmp bypassAuth bypass, logic flaws
CSRFMediumNo token validation on state-changing formsUnauthorized actions as victim
Open RedirectMediumheader("Location: ".$_GET['url'])Phishing, token theft
Path TraversalHighfile_get_contents($_GET['file'])Arbitrary file read
Session FixationMediumsession_id() accepted from userSession hijack
Insecure File UploadCriticalNo MIME/extension validationWebshell upload → RCE
Mass AssignmentHighextract($_POST), $$key = $valuePrivilege 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.