Is Your PHP Website Vulnerable? How to Detect and Fix It
A PHP website is vulnerable to hacks most often because of an end-of-life PHP version with unpatched known issues, an outdated dependency with a published vulnerability, or unvalidated user input reaching a database query or a file-loading function. Detecting it means checking the PHP version against the current end-of-life table, running a dependency audit, and scanning the live site with a real vulnerability scanner; fixing it means patching in that same order, oldest and most structural issue first.
A PHP website vulnerability is a specific, exploitable gap between what the running code assumes about its input or its own version's security coverage and what is actually true, rather than a vague sense that an older site is probably insecure.
- PHP 8.1 and all older versions are end of life; PHP's security support for 8.1 ended December 31, 2025, and PHP 8.2 loses its own security-only support at the end of 2026.
- The most common PHP-specific vulnerability classes are SQL injection, remote and local file inclusion, PHP object injection through unserialize(), and authentication bypass from missing access checks.
- Run `composer audit` (built into Composer 2.4 and later) against composer.lock in CI to catch known vulnerable dependencies before they reach production; it only flags packages with a published CVE or advisory, not custom application vulnerabilities like SQL injection written into your own code.
- WPScan, Nikto, and OWASP ZAP are real, current tools for scanning a live PHP site from the outside; none of them replace checking the PHP version and dependency versions from the inside.
- A compromised site does not just risk data; it directly damages the organic search and answer-engine pipeline a GTM motion increasingly depends on, which makes this a growth problem, not only a security one.
Which PHP versions are actually end of life right now?
PHP follows a predictable lifecycle: each release branch gets two years of full support (bug fixes and security patches), followed by two more years of security-only fixes, then end of life with no further patches of any kind from the PHP project. PHP 8.1's security support ended December 31, 2025, which means any vulnerability discovered in PHP 8.1 or earlier since then goes unpatched upstream permanently unless a third party backports a fix.
As of October 2026, PHP 8.2 is in its security-only window, running through the end of 2026, while PHP 8.3 and newer remain the actively maintained branches. Checking a site's PHP version is the single fastest way to know whether it is carrying structural risk: most hosting control panels and `php -v` from the command line will show it in seconds.
What are the most common ways a PHP site actually gets hacked?
SQL injection remains one of the most damaging and easiest to exploit: it happens when user input reaches a database query without being properly checked or parameterized, letting an attacker run their own queries. The impact ranges from reading all site data to planting spam links to creating a new administrator account outright.
File inclusion vulnerabilities come in two forms. Remote File Inclusion happens when user input controls a file-loading function, letting an attacker pull in and execute code hosted elsewhere; Local File Inclusion is the related case where the attacker instead points that function at sensitive files already on the server. Both can lead to full remote code execution, and both are prevented the same way: validating and whitelisting any input that influences which file gets loaded, rather than trusting it directly.
PHP object injection is a more PHP-specific risk, arising when user-controlled input reaches a call to `unserialize()`. The fix is straightforward and almost always available: use `json_decode()` instead of `unserialize()` for any data that could originate from outside the application. Authentication bypass, the fourth common class, is usually not a flaw in PHP itself but a missing access check somewhere in the application's own logic, which is why it shows up even on sites running a current PHP version.
Fixing SQL injection means replacing string concatenation with prepared statements, so user input is always passed as a bound parameter rather than interpolated directly into the query text:
// Vulnerable: user input concatenated directly into the query
$query = "SELECT * FROM users WHERE email = '" . $_GET['email'] . "'";
$result = $pdo->query($query);
// Safe: PDO prepared statement with a bound parameter
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(['email' => $_GET['email']]);
$result = $stmt->fetchAll();How do you actually detect these issues on a live site?
Start from the inside: check the PHP version against the current end-of-life table above, then run `composer audit` (built into Composer 2.4 and later) against composer.lock to check every PHP dependency against known security advisories pulled from Packagist and the FriendsOfPHP/security-advisories database. The command returns a non-zero exit code when it finds something, which makes it straightforward to wire into a CI pipeline so a vulnerable dependency fails a build automatically rather than reaching production silently.
`composer audit` only checks whether an installed package version matches one with a published CVE or advisory in that database; it has no visibility into the application's own code. A SQL injection or file inclusion flaw written directly into a site's custom PHP will not show up in a composer audit run, which is why the dependency check and the live-site scan below are both necessary rather than either one alone.
From the outside, a handful of established, free tools cover most of what a live site needs scanned. Nikto checks a web server for known-dangerous files, outdated server software, and common misconfigurations. OWASP ZAP is a dynamic application scanner that actively probes a running site for issues like injection points, rather than just reading its code. If the site runs WordPress, which a large share of PHP sites do, WPScan is purpose-built for it, enumerating themes, plugins, and known vulnerabilities specific to the WordPress ecosystem.
None of these replace each other. `composer audit` catches a known-vulnerable package before it ships; Nikto and ZAP catch what is actually exposed once the site is live; WPScan adds WordPress-specific coverage none of the others have. Running only one gives a false sense of completeness.
What should get fixed first once a problem is found?
Fix in order of structural risk, not order of discovery. An end-of-life PHP version comes first, since it means every future vulnerability in the language itself goes permanently unpatched until the upgrade happens; a vulnerable dependency flagged by composer audit comes second, since a published fix usually already exists and only needs to be applied. Application-level issues (unparameterized queries, unvalidated file-loading input, a stray unserialize() call) come third, since fixing them requires reviewing and changing the application's own code rather than running an update command.
For Roave/SecurityAdvisories specifically: it is a Composer package that actively blocks installing or updating to a version of a dependency with a known vulnerability, which turns the audit from something a team has to remember to run into something that fails the install step automatically. Adding it once is a small, durable fix compared to relying on human memory to re-run an audit command regularly.
Why does this matter for a GTM motion, not just security?
A compromised or blocklisted site does not just risk data; it directly damages the exact organic search and AI-answer-engine visibility a growing share of qualified pipeline now depends on, a point covered in the GTM challenges SaaS and AI startups actually face. Search engines actively flag and demote compromised sites, and an AI answer engine has no reason to cite a site that is serving spam or malware to some of its visitors.
Treating PHP and dependency security as a once-a-quarter afterthought, rather than a standing part of the same infrastructure a GTM motion runs content and conversion through, is a quiet but direct tax on the channel that is currently growing fastest.
Finding one of these issues is the first problem. The second is what happens to the business while it gets fixed: see how to take a PHP website offline without stopping the business behind it for how to contain an incident without going dark on customers at the same time.