Is PHP Running Correctly Between Your Host and Your WordPress Install?
The dashboard's version and the server's version are two different facts. Only one of them is load-bearing.
The week everything was on fire
On October 21, 2026, the PHP project shipped emergency fixes for two critical vulnerabilities — CVE-2026-109618 and CVE-2026-109619, collectively dubbed "php2shell." Both allow an unauthenticated attacker to execute code on a web server by sending a specially crafted request. The bug lives in the PHP engine itself, which means it fires before WordPress, before your security plugins, before anything you control. The only complete fix is a patched PHP build on the hosting server.
Cloudflare deployed WAF protections nine hours before public disclosure. Government sites went offline across Europe as a precaution. Exploit attempts were hitting honeypots four days before the patch existed. If you run a WordPress site, this was the week to know — precisely — what PHP build your server was executing.
We thought we knew. We had screenshots.
The banner we dismissed
Two weeks earlier, we had switched both of our sites to PHP 8.3 through the hosting dashboard — and verified it, with screenshots, at the time. So when a yellow banner appeared in the WordPress admin reading "Your website is running an outdated version of PHP (8.1.34)," we did what experienced admins do: we assumed the banner was stale. Plugins persist those notices; surely it was generated before the upgrade and never cleared.
That assumption was backwards. The banner wasn't stale. It was the only component in the entire stack reading the live runtime — and it was telling the truth while every dashboard in the chain lied.

The banner we almost dismissed — the only component in the stack reading the live runtime.
The diagnosis: three layers, two truths
Here's the structure that made this bug so hard to see. Bluehost shows PHP versions in two places — and neither one reads the runtime:
- The Bluehost dashboard (Websites → [site] → Advanced → PHP Version) — shows the branch only ("8.3"), and what it's actually showing is your intent, cached.
- cPanel → MultiPHP Manager — the hidden, more precise one: a per-domain table naming the actual package ("PHP 8.3 (ea-php83)"). Still a setting.
- WordPress → Tools → Site Health → Info → Server — the only layer that reads the PHP worker executing the request. This is the ground truth.

Two places, two settings — neither reads the runtime.
In our case: the dashboard said 8.3. MultiPHP Manager said 8.3. Site Health said 8.1.34. Three interfaces, two realities.
The smoking gun: one line in .htaccess
On LiteSpeed shared hosting, the PHP build that actually serves your site is chosen by a single machine-generated line at the bottom of your site's .htaccess:
# php -- BEGIN cPanel-generated handler, do not edit # Set the "ea-php81" package as the default "PHP" programming language.AddHandler application/x-httpd-ea-php81___lsphp .php .php8 .phtml # php -- END cPanel-generated handler, do not edit
That block is written by cPanel itself — not by us, not by any plugin. And the forensics were damning: the hosting platform's own PHP upgrader leaves snapshot files behind at every version change (.htaccess.phpupgrader.*). Ours showed the handler's complete history: PHP 8.0 → PHP 8.1. Never 8.3. The October 14 upgrade had updated the dashboard's state — and never touched the one line that decides what executes.

The smoking gun: one cPanel-generated line decides what executes.
The fix — and the trap inside it
The fix itself is one word in one line: change ea-php81 to ea-php83 in the handler. But the road there had two potholes worth documenting:
After the clean one-line edit: Site Health read 8.3.36 — the patched build — and the opcode cache statistics (fresh hit rate, newly allocated memory) confirmed the workers had reloaded with the new binary.

Ground truth after the fix: 8.3.36, the patched build.
The verification hierarchy (pin this)
| Source | What it tells you | Trust |
|---|---|---|
| Hosting dashboard | Intent / cached setting | Can be wrong — proven here |
| cPanel MultiPHP Manager | Per-domain setting + package name | Better — still a setting |
| .htaccess handler line | What the server is configured to load | Strong — read it directly |
| WordPress Site Health (Info → Server) | What is executing right now | Ground truth |
| Host support statements | Their tools' view — which may be the lying UI | Verify against runtime |
Check your own site in five minutes
- WordPress → Tools → Site Health → Info → Server — read the PHP version. Note the SAPI row too (
litespeedandmod_phpmean persistent workers — the riskiest model for state-reuse bugs). - Compare against the fixed builds for the current PHP vulnerabilities. For php2shell: 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12. If your branch shows the fixed build or higher, you're patched. If it shows anything lower — including a version your dashboard swears is current — you have the lie.
- If they disagree: check the handler line at the bottom of your site's
.htaccess(cPanel → File Manager → show hidden files). If it names an older package than your dashboard claims, that's your divergence. Fix the line (backup first), re-verify in Site Health. - Ask your host the questions that work: "What is the exact package build serving my domain — not the branch?" and "Was the handler in my .htaccess rewritten when I changed versions?" Expect honesty about limits: on shared hosting, patches apply server-wide and per-account confirmation generally isn't offered — which is exactly why the runtime check is yours to run.
What this incident actually taught
The scariest part of php2shell wasn't the vulnerability — it was the verification gap. A patched engine is the only complete fix, and the entire tooling chain between you and that engine can report success without delivering it. The plugin banner we almost dismissed knew more than the hosting dashboard, the support agent, and two weeks of our own screenshots.
Trust the runtime. Verify everything else.
Questions this article answers
Does the hosting dashboard show the exact PHP patch version?
No — it shows the branch (e.g. "8.3") and reflects your setting, not the runtime. The exact build (e.g. 8.3.36) is visible in WordPress Site Health.
How do I check what PHP version my site is actually running?
WordPress → Tools → Site Health → Info → Server → PHP version. It reads the executing worker, not a settings database.
Why did my PHP upgrade not take effect?
On LiteSpeed/cPanel shared hosting, the executed build is controlled by the cPanel-generated handler line at the bottom of your site's .htaccess. If the upgrade tooling didn't rewrite that line, the dashboard updates while the runtime doesn't.
What PHP versions fix the php2shell vulnerabilities (CVE-2026-109618 / CVE-2026-109619)?
PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12, released October 21, 2026. Older branches have no official fix — ask your host about backports.
Can a WordPress security plugin fix php2shell?
No. The bug is in the PHP engine, exploited before WordPress loads. Only the patched PHP build fixes it; a WAF reduces exposure.
Sources
- [TO ADD: PHP 8.3.36 release announcement — php.net]
- [TO ADD: NVD entry — CVE-2026-109618]
- [TO ADD: NVD entry — CVE-2026-109619]
- [TO ADD: Cloudflare WAF protection timeline — Cloudflare blog]
- [TO ADD: WordPress Site Health PHP-version check documentation — wordpress.org]