php2shell check — patch & mitigation status for CVE-2026-109618 / CVE-2026-109619, two critical unauthenticated remote-code-execution bugs in PHP, for URLs you are authorized to test. All verdict logic runs locally in your browser — the server only relays raw HTTP facts.
memory_limit=-1, set where applications can’t override it (e.g. php_admin_value in the FPM pool or Apache config); make sure no pool/directory/app setting brings a finite limit back.post_max_size: 8M without file uploads, 32M with them; keep upload_max_filesize below it. Also limit decoded request size, field count, multipart part count, header count and nesting depth at the web server / proxy — including requests without a usable Content-Length.RLIMIT_AS / RLIMIT_DATA — they can cause the vulnerable allocation failure.session.upload_progress.enabled=0 in php.ini, the FPM pool or server config (applies before request parsing), then restart every worker. Not via ini_set() or FPM .user.ini. Blocks the confirmed session paths only.fatal_error_backtraces=0 and restart every worker (blocks the confirmed backtrace path only).error_reporting, display_errors, @) does not help.Want to run the exact same inert checks yourself directly from your terminal or CI? Below is the curl test script representing the 7 requests (1 GET + urlencoded & multipart across POST, PUT, and PATCH). It never sends upload-progress fields or file parts, so it is safe to run on authorized targets.
How to read. PHP detection: an X-Powered-By: PHP/… header (only PHP itself counts, not Next.js/Express/KPHP) or a PHP session cookie on any response; the version is compared with
the patched-release list shown above the result (kept server-side by the operator). Absent
banners (CDN stripping, expose_php=Off) report unknown — a missing banner
is not safety. Block test: an upload-style (multipart) request vs a normal form POST,
on POST, PUT and PATCH — blocking POST alone is not enough, PHP 8.4 apps can read multipart
on other methods too. ASSUMED VULNERABLE (red) means such requests flow through to
the backend and no patched runtime could be confirmed — treat the site as vulnerable until
a patched PHP version is verified. NO PHP
DETECTED means no POST-shaped request is processed at this URL (connections dropped
or 405/501 replies) and there are no PHP indicators (banner, session cookie) — consistent
with a static site: nothing to exploit at this URL.
Probes. One URL at a time, seven inert requests (1 GET, then a normal + multipart request per method — never an upload-progress field, never a file part, so the vulnerable code path is never engaged). Redirects are followed like a browser (301/302/303 convert to GET, 307/308 keep the method, max 3 hops) — the first-hop status decides the verdict. A rejection at the CDN/WAF stops the request before PHP parses the body; the exact same status produced inside the application happens after — and the two cannot be told apart remotely, so the checker says so instead of over-claiming. A CDN-block also does not help if the origin server is directly reachable. A URL that refuses connections shows green OFFLINE — nothing is serving there, so there is nothing to assess.
Scope. This is a patch-status / configuration check, not a vulnerability
probe: it never sends exploit-shaped requests (no session cookie, no file part, no
upload-progress field, no stalling). Results live only in your browser session — there is no
export endpoint; the tested URL stays in the address bar as /… for
bookmarking/sharing and is never sent anywhere. Every submission and every poll
solves a small proof-of-work in your browser (an abuse brake, ~1s once per check).
Definitive fix = a patched PHP runtime.
No guarantees. Results are best-effort indications from the outside: banners can lie, caches can hide the origin, and edge behavior differs per route. This is not a vulnerability assessment — verify on the host. Docs for humans and LLMs: llms.txt.