Remote code execution via out-of-memory state corruption
Confirmed impact: unauthenticated remote code execution as the web worker account.
CVE-2026-109618 · GHSA-w8hw-w9fx-j79w · CVSS 9.2
PHP2Shell gives an unauthenticated attacker code execution as your web worker, and one of the two bugs can also read freed worker memory. For a Solana dApp, trading dashboard, NFT mint or exchange tool running PHP, every secret that process could reach is now in scope: hot-wallet keys, RPC provider keys, exchange API secrets, and any mnemonic in the environment.
PHP2Shell is two critical (CVSS 9.2), unauthenticated remote-code-execution bugs in the PHP engine itself, fixed on 21 October 2026 and exploited in the wild before the patch shipped. They hit any web-facing PHP worker, whatever framework sits on top.
Confirmed impact: unauthenticated remote code execution as the web worker account.
CVE-2026-109618 · GHSA-w8hw-w9fx-j79w · CVSS 9.2
Confirmed impact: unauthenticated memory disclosure and remote code execution as the web worker account.
CVE-2026-109619 · GHSA-6wmf-4rv5-p3rp · CVSS 9.2
The advisories describe the impact as code execution and memory disclosure as the web worker. They do not publish a list of what secrets exist on your box; that inventory is yours. The rule of thumb below is ours: if the PHP process could read it, an attacker running as that process could read it too.
Sources:php.net release archive and security advisory (2026)GHSA-w8hw-w9fx-j79wGHSA-6wmf-4rv5-p3rp
Work top to bottom. Steps 1 and 2 stop the bleeding; step 3 assumes the keys already leaked; steps 4 and 5 confirm and contain. Tick items off as you go; the list is stored only in this browser.
Upgrade to the fixed release for your branch (8.5.12 / 8.4.27 / 8.3.36 / 8.2.35). PHP 8.1 and older get no official fix: move off them.
An upgrade only protects processes started after it. Restart PHP-FPM, Apache mod_php, FrankenPHP, LiteSpeed lsphp and any long-running CLI workers so none still run the old build.
If a vulnerable worker could read a secret, treat it as leaked. Do this before you have proof of a breach, not after.
Find committed keypairs, seed phrases and provider keys so you know exactly what to rotate and where it leaked from.
Use the exposed-key scanner below (local, nothing uploaded), or phpshield scan on the host
Watch the wallets you believe were exposed for unexpected movement, and keep watching after you rotate.
Drop a .env, a keypair file, or a whole repo folder. PHPShield finds committed Solana keypairs, BIP39 seed phrases, and RPC / exchange API keys. Keypairs show the public address so you know which wallet to rotate; every secret itself stays masked.
Drop .env files, keypair JSON, or source files here, or click to choose
Read locally in this tab. Nothing is uploaded.
Scans for exposed private keys, Solana keypairs and BIP39 seed phrases. Secrets are masked before anything is shown; only the public wallet address is displayed, so you know which wallet to rotate. Everything runs in your browser; nothing is uploaded.
Enter a Solana address to list its most recent transactions straight from an RPC node, then turn on Watch to keep checking every 60 seconds while this tab is open. Each new transaction is marked when the wallet itself signed it; that needs the private key, so a signature you did not make means someone else has it. This is a read-only lookup (getSignaturesForAddress, getParsedTransactions). PHPShield never builds, signs or sends a transaction.
The default is PublicNode's free endpoint, which answers browser requests but keeps only the last few days of history. For older activity, paste your own RPC URL or run phpshield wallet ADDRESS. api.mainnet-beta.solana.com refuses requests from browsers.
phpshield wallet <ADDRESS> --watch --interval 60s \ --webhook "$SLACK_WEBHOOK_URL" --webhook-format slack
A token delegate (an approval) can move up to an approved amount out of a token account without the owner signing. Enter a wallet address to list every spl-token and Token-2022 account that still has one. This only reads (getTokenAccountsByOwner); revoking is done from your own wallet.
The free public endpoints refuse this lookup from a browser: api.mainnet-beta.solana.com blocks every browser request, and PublicNode blocks getTokenAccountsByOwner. Use the RPC URL from your provider or your own node. No RPC URL? phpshield delegates ADDRESS runs the same check from a terminal against the public endpoint.
Once you have patched and rotated, change the architecture so the next RCE cannot reach a signing key at all.
Keep the raw private key out of the application entirely. The web tier asks a dedicated signer (hardware token, KMS, or a separate signing service on its own host) to sign; an RCE in PHP then yields no key material.
Store env files and key material outside any web-served directory, and never commit them. Secrets under public/, wp-content/, dist/ or similar are both reachable and often publicly served.
Run PHP as an unprivileged user that can read only what it must. Use open_basedir and disable_functions, and give the worker no standing access to keys it does not need for the current request.
Put signing behind a narrow, audited internal API with its own authn and rate limits, on a host that does not serve web requests. A compromised front end can then request a signature but cannot exfiltrate the key.
The CLI scans your whole server for exposed keys and signs of compromise. phpshield wallet ADDRESS --watch watches a wallet from a server or cron job and can post to Slack or Discord, and phpshield delegates ADDRESS lists token approvals.
Advisory facts: CVE-2026-109618 and CVE-2026-109619, published 2026-10-21.