PHP still powers a huge share of the web, including WordPress, Laravel, Drupal, and countless custom apps. That popularity makes PHP a frequent target. When vulnerabilities show up — in the runtime, in frameworks, or in plugins — the impact is rarely limited to one site.
This article breaks down the PHP issues teams keep running into, what they mean in practice, and what you need to do to fix them.
The core problem: outdated PHP is still everywhere
One of the most common findings in site audits and incident response is simple: the server is running an unsupported or end-of-life PHP version.
Older PHP releases stop receiving security patches. That means known vulnerabilities remain exploitable indefinitely. Attackers do not need a clever zero-day when thousands of hosts are still on versions that were retired years ago.
What to do:
- Check your current version:
php -von the server, or a phpinfo page in staging. - Move to a currently supported PHP release (as of now, plan around active PHP 8.x branches).
- Test applications and plugins on staging before switching production.
- Set a calendar reminder to reassess PHP versions at least twice a year.
If your host controls the runtime, open a ticket and confirm which PHP versions are available and which are officially supported.
Common PHP vulnerability classes
1. SQL injection
User input gets concatenated into SQL queries. Attackers can read, modify, or destroy data.
Fix:
- Use prepared statements / parameterized queries everywhere.
- In WordPress, use
$wpdb->prepare(). - In modern PHP apps, prefer PDO or mysqli with bound parameters.
- Never build SQL strings from
$_GET,$_POST, or cookie values.
2. Cross-site scripting (XSS)
Unescaped output lets attackers inject scripts into pages viewed by other users.
Fix:
- Escape on output (
htmlspecialchars, Twig/Blade auto-escaping, WordPress escaping helpers). - Use Content Security Policy (CSP) headers where possible.
- Sanitize rich text with a strict allow-list library, not homemade filters.
3. Remote file inclusion / local file inclusion
Dynamic include / require paths based on user input can expose files or execute remote code.
Fix:
- Never include files from request parameters.
- Map allowed files through a server-side allow-list.
- Disable dangerous PHP settings when not required (see hardening section below).
4. Insecure deserialization
Untrusted serialized data can lead to object injection and remote code execution in PHP applications.
Fix:
- Do not pass serialized PHP objects from users or cookies.
- Prefer JSON for data exchange.
- If serialization is unavoidable, sign payloads and validate integrity before use.
5. Vulnerable plugins, themes, and Composer packages
On WordPress and other CMS platforms, the runtime may be fine while a plugin is the entry point. Supply-chain issues in Composer packages create the same risk for custom apps.
Fix:
- Remove unused plugins and themes completely (not just deactivate).
- Update remaining plugins, themes, and dependencies promptly.
- Monitor CVE/security feeds for your stack.
- Run
composer auditin custom PHP projects.
6. Weak authentication and session handling
Predictable session IDs, missing cookie flags, or custom auth shortcuts create account takeover paths.
Fix:
- Use framework session handling instead of homemade cookies.
- Set cookie flags:
Secure,HttpOnly, andSameSite. - Enforce strong password storage (
password_hash/password_verify). - Add rate limiting and multi-factor authentication where appropriate.
PHP configuration issues that increase blast radius
Even secure application code can be undermined by risky PHP settings.
| Setting / behavior | Risk | Recommended direction |
|---|---|---|
display_errors = On in production | Leaks paths, tokens, query details | Off in production; log errors instead |
| Allowing dangerous functions | Easier code execution after a foothold | Disable exec, shell_exec, system, passthru, etc. if unused |
| Writeable web root | Attackers can drop webshells | Least-privilege file permissions |
| Outdated extensions / libraries | Known CVEs remain exploitable | Keep extensions and OS packages updated |
What folks need to do: a practical fix checklist
Step 1 — Inventory
- PHP version on every environment
- Framework/CMS version
- Plugins, themes, and Composer packages
- Who can deploy and who has admin access
Step 2 — Patch the runtime
- Upgrade to a supported PHP 8.x release
- Confirm extensions still work
- Re-test critical workflows
Step 3 — Patch the application layer
- Update CMS core, plugins, and themes
- Remove abandoned components
- Apply vendor security releases the same week they ship when possible
Step 4 — Fix code-level issues
- Replace raw SQL with prepared statements
- Escape all output
- Eliminate dynamic includes based on user input
- Review file upload handling (type, size, storage location, execution permissions)
Step 5 — Harden the server
- Turn off detailed error display in production
- Restrict dangerous PHP functions if not required
- Serve the app over HTTPS only
- Lock down file permissions and SFTP/SSH access
- Keep daily backups that are stored off the web root
Step 6 — Monitor and verify
- Enable logging and review it after changes
- Use malware/integrity scanning on CMS sites
- Re-scan after major upgrades
- Document what changed and when
WordPress-specific notes
A large percentage of real-world PHP incidents involve WordPress ecosystems rather than custom frameworks. Priority actions:
- Keep WordPress core auto-updates enabled for minor releases
- Delete unused plugins instead of leaving them inactive
- Prefer well-maintained plugins with a clear update history
- Limit admin users and require strong authentication
- Block PHP execution in upload directories when the host allows it
If a plugin starts throwing fatal errors or is no longer maintained, removing it is often safer than leaving a broken or abandoned component installed.
How to respond if you think you were already hit
- Take a backup snapshot before major cleanup (for forensics).
- Put the site into maintenance mode if users are at risk.
- Rotate CMS admin passwords, hosting passwords, FTP/SFTP, database, and API keys.
- Remove unauthorized admin users, cron jobs, and unknown scheduled tasks.
- Compare core/plugin files against clean versions.
- Patch the original vulnerability so attackers do not walk right back in.
- Review access logs around the time of the incident.
If customer data may have been exposed, follow your legal and notification obligations for your jurisdiction.
Bottom line
Most PHP security failures are not mysterious. They cluster around:
- outdated PHP versions,
- unpatched plugins and dependencies,
- injection and unsafe file handling,
- weak server configuration.
The fix path is equally clear: run supported PHP, keep dependencies current, remove what you do not use, write safe data access and output code, and harden the runtime.
Teams that treat those steps as routine maintenance — not emergency-only work — avoid most of the incidents that still catch everyone else.