Skip to content
SecurityPHP2Shell affects most WordPress sites. Am I affected? →
presscomet
Security

Was my WordPress site hacked by PHP2Shell?

You patched PHP for PHP2Shell — but if your site was exposed first, patching doesn’t evict anyone already inside. Here’s a calm, defensive checklist of what to look for in your logs, files and WordPress admin.

By the Presscomet teamPublished 13 min read

On this page
  1. A patch doesn’t undo a break-in
  2. Were you even exposed?
  3. The compromise checklist
  4. What the logs reveal
  5. Signs on the server
  6. Signs inside WordPress
  7. You found something — now what
  8. Why PHP2Shell can’t touch Presscomet

A patch doesn’t undo a break-in

If you’ve just updated PHP for PHP2Shell (the pair of PHP-runtime bugs CVE-2026-109618 and CVE-2026-109619), well done — but notice what the update does and doesn’t do. Patching PHP stops new exploitation. It does nothing to anything an attacker already planted while your site was exposed: a rogue administrator account, a backdoor file in your uploads folder, a scheduled task that re-infects you after every clean-up.

That’s the uncomfortable part of any serious vulnerability. The fix and the clean-up are two different jobs. This guide is only the first one: working out whether anyone got in. It’s deliberately calm and entirely defensive — a list of things to look for, not a way to attack anything. If you turn up a warning sign, the recovery checklist is where you go next.

Who this is for

You most need this if your site was online on an unpatched PHP version at any point in the second half of October 2026. If you’re on a managed host that patched for you before the vulnerability was public, your window may have been tiny or zero — but it’s worth confirming that with a quick look, which is exactly what the list below is.

Were you even exposed?

Before you comb through logs, establish two things: were you running a vulnerable PHP build, and for how long. If the answer to the first is “no” — your host patched or mitigated before you were ever reachable on an unpatched runtime — the rest of this becomes a quick sanity check rather than an investigation.

The dates that frame the window:

  1. 1 Aug 2026

    Bugs first reported

    Roughly when researchers reported the issues to PHP. Security vendors suggest reviewing admin logins back to here as a precaution — not because exploitation started then, but because it’s a safe outer edge.
  2. 17 Oct 2026

    First attempt on record

    Amazon’s threat-intelligence team logged an exploitation attempt against its sensors, four days before patches — while the bugs were still under embargo.
  3. 20–21 Oct 2026

    Details leak, then fixes ship

    Information spread publicly on 20 October; PHP released 8.5.12, 8.4.27, 8.3.36 and 8.2.35 on 21 October. Mass scanning climbed from thousands of attempts to millions after the announcement.
  4. The moment you patched

    Your window closes

    Your exposure window runs from whenever your server became reachable on an unpatched build until the moment patched PHP workers restarted. If that overlaps 17 October onward, check carefully.

Not sure whether the version you were on was vulnerable? This three-question checker runs entirely in your browser and tells you where a given PHP version stands. It won’t tell you whether you were hacked — nothing automatic can — but it settles the “was I even vulnerable?” question first.

Interactive checker

Am I affected by PHP2Shell?

Runs in your browser · nothing is sent

  1. PHP version
  2. Server API
  3. Hosting
  4. Verdict

Find it in wp-admin under Tools › Site Health › Info › Server. Copy the whole number, e.g. 8.3.14.

Try:

Still unsure what your host actually did, or when? That’s a fair question to put to them directly — our guide on how to ask your host whether they’re patched has a copy-and-paste email, including the key question of when PHP was restarted.

The compromise checklist

Here’s the whole thing as an interactive list. Tick items as you check them; press Found this on anything that looks wrong. Your ticks are saved in this browser, so you can stop and come back. The sections after it explain each group in more detail, including the commands to run.

Interactive checklist

PHP2Shell indicators of compromise

0/14

checked

1 · Web & WAF logs
2 · PHP & error logs
3 · The server
4 · WordPress

Ticks are saved in this browser only, so you can come back later.

What the logs reveal

Logs are your best witness, because PHP2Shell’s most reliable triggers leave a shape in them. The attack paths that worry researchers most go through PHP’s multipart parsing and session upload-progress handling, which run before WordPress loads a single line. So the tell-tale requests often land on URLs that have no business receiving an upload at all.

In your web server access log (and your WAF log, if you have one), you’re looking for:

  • Multipart POSTs to the wrong places — upload-style requests aimed at your homepage, a feed, or paths that never accept files.
  • The PHP_SESSION_UPLOAD_PROGRESS field — if your WAF records request bodies or field names, this one is a strong signal because it was a demonstrated remote trigger.
  • Oversized requests — abnormally large multipart bodies or thousands of form fields.
  • Oversized PHPSESSID values — a memory-disclosure technique leaked around 67 KB of server memory per attack through an inflated session cookie.

In the PHP error log, the signature of the out-of-memory technique is a spike of Allowed memory size … exhausted messages, sometimes alongside worker segfaults. On their own these have ordinary causes, so don’t panic at one. What matters is a sudden cluster around your exposure window — then line those timestamps up against the access log and see what was being requested at the same moment.

Scan logs for PHP2Shell patterns (adjust paths and dates)
# Upload-progress trigger and multipart posts in the access log$ grep -i 'PHP_SESSION_UPLOAD_PROGRESS' /var/log/nginx/access.log*$ grep -iE 'multipart/form-data' /var/log/nginx/access.log* | grep ' POST '# Memory-exhaustion spikes and worker crashes in the PHP error log$ grep -iE 'Allowed memory size|exhausted' /var/log/php*-fpm.log*$ grep -iE 'signal 11|segfault|child .* exited' /var/log/php*-fpm.log*# POSTs to the homepage around the exposure window (adjust the date)$ grep ' POST / ' /var/log/nginx/access.log | grep '17/Oct/2026'

A WAF in front can hide the evidence

If a CDN or web application firewall terminated requests before your origin, your server logs may only show clean traffic while the real attempts sit in the CDN’s logs. Check both. “Our WAF blocked it” is reassuring, but confirm the blocks are actually in the WAF log rather than assumed.

Signs on the server

If an attempt turned into code execution, the next traces are on the filesystem and in the process list. Successful code execution with the web server’s privileges typically shows up as one or more of the following.

Out-of-place code
.php files in wp-content/uploads, or unfamiliar files in the web root and mu-plugins
Spawned processes
sh, bash, curl, wget, python or perl with php-fpm or Apache as the parent
Outbound traffic
Connections from PHP processes to unfamiliar hosts or IPs
New persistence
Cron jobs, systemd timers or SSH keys you didn’t add

The media library is the clearest tell: it should contain images, video and documents, never executable PHP. A single .php file in wp-content/uploads is reason enough to treat the site as compromised. The same goes for anything in mu-plugins you can’t explain, since must-use plugins load automatically and can’t be switched off from the admin.

Defensive checks over SSH (run from the WordPress root)
# PHP files where only media should live$ find wp-content/uploads -type f -name '*.php'# PHP files changed since the first recorded attempt$ find . -type f -name '*.php' -newermt '2026-10-17' -not -path './wp-content/cache/*'# Must-use plugins (there may legitimately be none)$ ls -la wp-content/mu-plugins 2>/dev/null# Administrators and when they were created (WP-CLI)$ wp user list --role=administrator --fields=ID,user_login,user_email,user_registered# Core files that differ from the official release$ wp core verify-checksums

None of this modifies anything — it only lists and compares. If a command above surfaces something you can’t account for, don’t start deleting. Preserving the evidence is what lets you (or a professional) work out how far the intrusion went, and the recovery checklist explains the order to clean up in.

Signs inside WordPress

Some evidence never touches a log you can read — but it surfaces inside WordPress and in Google. These are the signs a non-technical site owner is most likely to notice first, and they’re worth checking even if you have no server access.

  1. Step 1: Unknown administrators

    Open Users › All Users and filter by Administrator. An account you didn’t create — especially one registered during your exposure window — is a serious red flag. Note it; don’t delete it yet.
  2. Step 2: Plugins you didn’t install

    Check Plugins › Installed Plugins and the Must-Use tab. Attackers add plugins to keep a foothold, and must-use plugins are a favourite hiding place because they can’t be deactivated from the dashboard.
  3. Step 3: Spam pages and redirects

    Search site:yourdomain.com for pages you never wrote — pharma, casino, counterfeit goods or foreign-language spam. Redirects often fire only for visitors arriving from Google, or only on mobile, so you may not see them while logged in.
  4. Step 4: Search Console security issues

    Open Search Console › Security & Manual Actions › Security issues. A “Hacked: content injection” or similar flag is Google telling you it found something you haven’t.
  5. Step 5: Host and antivirus warnings

    A malware, spam or resource-abuse notice from your host, or readers reporting that their antivirus blocks your site, is external confirmation worth taking seriously.
  6. Step 6: Unexplained admin logins

    If you log logins, review successful administrator sign-ins back to 1 August 2026 for odd times, locations or IPs. No login log? Your host’s access logs are the fallback.

Not every scare is a hack

A white screen, a “critical error on this website” message or a database-connection error after an update is usually a plugin, theme or PHP-version conflict — not an intruder. PHP2Shell compromise looks like someone else in control: content you didn’t create, accounts you didn’t make, traffic you can’t explain.

You found something — now what

If you flagged anything above, treat the site as compromised until you’ve proven otherwise. The instinct is to start deleting the scary files immediately; resist it for ten minutes, because deleting evidence makes it far harder to tell how far the attacker got and whether they left a way back in.

  1. Step 1: Contain, don’t delete

    Put the site behind maintenance at the server or CDN level, or take it offline. A maintenance-mode plugin isn’t enough — it runs inside the compromised software.
  2. Step 2: Preserve the evidence

    Snapshot files, a database export and your logs before changing anything. Even an infected copy is useful, and it’s a fallback if the clean-up goes wrong.
  3. Step 3: Confirm PHP is patched

    There’s no point cleaning while the door is still open. Make sure PHP is on a fixed build (8.5.12, 8.4.27, 8.3.36, 8.2.35 or a vendor backport) and that workers were restarted.
  4. Step 4: Rotate every secret

    Because PHP2Shell can leak worker memory, assume passwords, tokens and API keys were exposed. Our guide on rotating WordPress security keys and secrets walks through the full list.
  5. Step 5: Clean up in order

    Follow the WordPress hacked recovery checklist: restore a clean backup from before your exposure window, or rebuild from official sources, then request a Google review.

For a site that handles payments, member accounts or personal data, bring in professional help early — you may have legal duties to work out what was accessed, not just to make the symptoms disappear.

Why PHP2Shell can’t touch Presscomet

PHP2Shell is a bug in the PHP runtime. Presscomet has no PHP runtime — it runs the same wp-admin, block editor, URLs and REST API on Node.js with a single SQLite file — so PHP2Shell and the whole class of PHP-runtime vulnerabilities simply don’t apply to it. There’s no PHP worker memory to leak and no multipart parser to abuse.

That’s a genuine reduction in attack surface, not a magic shield, and it’s worth being honest about the edges. Presscomet still has its own software to keep updated — Node.js, its libraries and the server it runs on — and its own login to protect, so nobody should call it unhackable. It also doesn’t run PHP plugins: the common jobs (SEO, forms, SMTP, redirects, security, custom fields) are built in, but WooCommerce stores aren’t supported. The trade-offs are laid out on our WordPress security page.

Clean first, then consider moving

Migrating an infected site moves the infection. If this checklist turned something up, recover first. Once you’re clean, you can check what would move over to Presscomet — it reads your public site and never changes anything on your server.

And if you came through this clean: keep your logs for a few weeks, re-check your administrator list and a site: search next week, and — if you were exposed at all — rotate your secrets as a precaution. Then run the broader WordPress security checklist so the next runtime bug is someone else’s emergency, not yours.

Sources

Facts checked against these sources on October 24, 2026. Things change quickly; the vendor advisory always wins.

  1. [1]PHP2Shell advisory (indicators of compromise and detection) — Sophos
  2. [2]PHP2Shell: session upload-progress as a remote trigger — Imperva
  3. [3]PHP2Shell and WordPress: what to look for — Meow Apps
  4. [4]PHP2Shell exploitation started days before patches — SecurityWeek
  5. [5]PHP2Shell FAQ (exploitation status) — watchTowr
  6. [6]PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 security releases — PHP.net
  7. [7]FAQ: My site was hacked — WordPress.org Documentation
  8. [8]Security issues report — Google Search Console Help

Frequently asked questions

How do I tell if my WordPress site was hacked by PHP2Shell?

Check four places. In your web and WAF logs, look for multipart/form-data POSTs to URLs that don’t accept uploads, requests carrying the PHP_SESSION_UPLOAD_PROGRESS field, unusually large multipart bodies, and oversized PHPSESSID values. In the PHP error log, look for spikes of “Allowed memory size … exhausted” and worker segfaults. On the server, look for shells or download tools spawned by php-fpm or Apache, new or modified .php files in wp-content/uploads, and outbound connections to unfamiliar hosts. In WordPress, look for unknown administrators, plugins you didn’t install, spam pages and Search Console security warnings.

If I’ve already patched PHP, do I still need to check for a compromise?

Yes, if your site was online and unpatched at any point while PHP2Shell was being probed. Patching PHP stops new exploitation, but it does nothing to a backdoor, rogue admin account or malicious file that an attacker planted before you patched. The first recorded attempt was 17 October 2026 and fixes shipped on 21 October, so a site exposed during that window should be checked, not assumed clean.

What is the PHP_SESSION_UPLOAD_PROGRESS field and why does it matter?

It’s a field name tied to PHP’s session upload-progress feature, which runs during multipart form parsing — before your application code executes. Several demonstrated PHP2Shell techniques used it as a remote trigger, so requests containing PHP_SESSION_UPLOAD_PROGRESS, especially to pages that never handle uploads, are worth flagging in your logs. Seeing it is not proof of compromise on its own, but it belongs in your review.

Does a spike of “Allowed memory size exhausted” errors mean I was hacked?

Not on its own — memory-exhaustion errors have ordinary causes like heavy plugins or large imports. But one PHP2Shell technique relies on forcing an out-of-memory condition at the wrong moment, so a sudden cluster of memory-exhaustion errors and worker segfaults (for example “exited on signal 11”) around 17–23 October 2026 is a reason to look harder at the same timestamps in your access log.

How far back should I review admin logins?

Security vendors suggest reviewing successful administrator logins back to 1 August 2026 as a precaution, since that’s roughly when the bugs were first reported. Look for logins at odd hours, from unfamiliar locations or IP addresses, or for accounts that shouldn’t have been active. Keep in mind many sites don’t log logins by default, in which case your host’s access logs are the next best record.

I found nothing. Can I be sure my site is clean?

You can be reasonably confident, not certain. Absence of evidence isn’t proof, especially if your logs don’t go back far enough or a WAF sat in front of the origin. Keep your logs for a few weeks, re-check your administrator list and a site: search once more the following week, and watch for host warnings. If your site handles payments or personal data, consider a professional review.

Run WordPress without a PHP runtime to patch.

Presscomet keeps your wp-admin, editor, URLs and content, and serves pages without PHP or MySQL. Check your site for free, then migrate in one click — your old site is only ever read.

Check my site