Back to Guides
Guide4 November 2026

What are the most common PHP security vulnerabilities and how to fix them?

Decloak is an AI-powered web security intelligence platform that scans a site's HTTP/TLS posture, JavaScript, and third-party scripts to produce a report anyone can read. This guide is part of Decloak's library of practical, source-backed security guidance.

In this guide
  1. Key takeaways
  2. What is Cross - Site Scripting (XSS) in PHP and how do I prevent it?
  3. How does SQL Injection happen in PHP and what concrete steps stop it?
  4. Why is Cross - Site Request Forgery (CSRF) a risk for PHP apps and how can I mitigate it?
  5. What is Remote Code Execution (RCE) in PHP and how do I block it?
  6. How do File Inclusion vulnerabilities work in PHP and how can I secure includes?
  7. What causes Session Hijacking or Fixation in PHP and how do I protect sessions?
  8. How does Insecure Direct Object Reference (IDOR) appear in PHP and how to avoid it?
  9. Why are Unrestricted File Uploads dangerous in PHP and what concrete validation should I apply?
  10. What makes Insecure Cryptography a problem in PHP and how should I hash passwords correctly?
  11. How does Code Injection via `eval` or `preg_replace('/e/')` happen in PHP and how to eliminate it?
  12. How can I verify that my PHP site is not vulnerable to these issues?
  13. What ongoing practices keep PHP applications secure?

Key takeaways

What is Cross - Site Scripting (XSS) in PHP and how do I prevent it?

XSS occurs when user - supplied data is echoed into HTML without proper encoding, letting attackers run malicious scripts in a visitor’s browser. Prevent XSS by always passing dynamic output through htmlspecialchars with ENT_QUOTES and the correct charset, and by using a templating engine that auto - escapes.

echo htmlspecialchars($_POST['comment'], ENT_QUOTES, 'UTF-8');

Additionally, set the Content - Security - Policy header to restrict script sources.

How does SQL Injection happen in PHP and what concrete steps stop it?

SQL injection happens when raw request data is concatenated into a query string, allowing attackers to change the query logic. The single most effective mitigation is to use prepared statements with bound parameters, either via PDO or MySQLi.

$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $_GET['id']]);

Never interpolate variables directly into SQL strings, and disable magic_quotes_gpc if it is still enabled.

Why is Cross - Site Request Forgery (CSRF) a risk for PHP apps and how can I mitigate it?

CSRF tricks an authenticated browser into sending a state - changing request to your site. Mitigate CSRF by requiring a per - session token for any POST, PUT, DELETE, or other side - effect actions and by checking the Origin or Referer header.

if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
 die('Invalid CSRF token');
}

Regenerate the token on login and store it in a secure, HttpOnly cookie.

What is Remote Code Execution (RCE) in PHP and how do I block it?

RCE occurs when user input reaches functions that execute shell commands, such as exec, shell_exec, or back - ticks. Block RCE by avoiding these functions entirely for user - controlled data. If you must run a command, use proc_open with a whitelist of allowed arguments and escape everything with escapeshellarg.

$cmd = 'ls ' . escapeshellarg($safeDir);
$output = shell_exec($cmd);

Also disable allow_url_fopen and allow_url_include in php.ini.

How do File Inclusion vulnerabilities work in PHP and how can I secure includes?

File inclusion vulnerabilities let an attacker control the path passed to include or require, leading to arbitrary code execution. Secure includes by using a whitelist of allowed files and never concatenating user input directly into the path.

$allowed = ['home.php','about.php'];
$page = $_GET['page'];
if (in_array($page, $allowed, true)) {
 include __DIR__.'/pages/'.$page;
}

Keep open_basedir enabled to restrict file system access.

What causes Session Hijacking or Fixation in PHP and how do I protect sessions?

Session attacks happen when session IDs are predictable, transmitted over insecure channels, or not flagged as HttpOnly/Secure. Harden sessions by:

How does Insecure Direct Object Reference (IDOR) appear in PHP and how to avoid it?

IDOR occurs when internal identifiers are exposed in URLs and used without access checks. Mitigate IDOR by validating that the authenticated user owns the requested resource before fetching it.

$docId = (int)$_GET['id'];
$stmt = $pdo->prepare('SELECT * FROM documents WHERE id = :id AND user_id = :uid');
$stmt->execute(['id'=>$docId,'uid'=>$_SESSION['user_id']]);

Never rely solely on obscurity of IDs.

Why are Unrestricted File Uploads dangerous in PHP and what concrete validation should I apply?

Allowing any file type to be saved in a web - accessible directory lets attackers upload PHP shells or overwrite critical files. Implement strict validation:

$allowed = ['image/jpeg','image/png'];
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($_FILES['avatar']['tmp_name']);
if (!in_array($mime,$allowed)) { die('Invalid file type'); }
$dest = '/var/www/uploads/'.bin2hex(random_bytes(16)).'.jpg';
move_uploaded_file($_FILES['avatar']['tmp_name'],$dest);

What makes Insecure Cryptography a problem in PHP and how should I hash passwords correctly?

Using weak hashes like MD5 or storing keys in plain text exposes credentials. Use password_hash with PASSWORD_DEFAULT (currently bcrypt) and password_verify for password storage. For symmetric encryption, use openssl_encrypt with a strong cipher (e.g., AES - 256 - GCM) and store keys in a secret manager, not in source code.

$hash = password_hash($plainPassword, PASSWORD_DEFAULT);
if (password_verify($loginPass,$hash)) { /* authenticated */ }

How does Code Injection via eval or preg_replace('/e/') happen in PHP and how to eliminate it?

Code injection runs attacker - supplied strings as PHP code. The safest fix is to remove eval, create_function, and the deprecated /e modifier entirely. Refactor logic to use native PHP functions or callbacks.

// Bad
eval($_POST['code']);
// Good - use a whitelist of allowed actions
$action = $_POST['action'];
if ($action === 'save') { saveData(); }

How can I verify that my PHP site is not vulnerable to these issues?

Run a passive web scan (e.g., Decloak free scan) on your live URL. The scanner checks HTTP/TLS posture, static HTML, rendered network behaviour, JavaScript CVE patterns, tag manager settings, third - party domains, platform - specific misconfigurations, and provides an AI - written executive summary - all without needing credentials. Review the findings, fix the reported items, and re - scan to confirm remediation.

What ongoing practices keep PHP applications secure?


For a quick, no - account scan of your live PHP site, try Decloak’s free scanner. It returns a graded report in about 15 seconds, highlighting exactly the issues discussed above.

Free security scan

See what's actually exposed on your site.

Decloak's free scan runs in about 15 seconds, no account required, and covers:

  • HTTP/TLS security posture
  • JavaScript CVEs
  • Exposed Supabase/Lovable/Base44 misconfigurations
  • AI-written executive summary