What this checker does to your site
php2shell.fyi is a public checker for the PHP2Shell vulnerabilities (CVE-2026-109618 and CVE-2026-109619). Someone submits a URL. The normal check is passive: it reads the ordinary response to that URL, as a visitor would get it, and reports the public signals in it. A separate active scan sends test requests, but only when the user starts it and confirms that they may test the site.
Requests
- At most three ordinary
GETrequests per check: the submitted URL, plus redirects to the same host or itswwwtwin. - No other paths, no request bodies, no payloads, no uploads, no cookies and no credentials.
- HTTPS on port 443 only. Redirects to other hosts are not followed.
- Before and after each request, the checker resolves your host through Cloudflare's DNS-over-HTTPS resolver (
cloudflare-dns.com). Private and reserved addresses stop the check.
How to recognise it
- User-Agent:
PHP2Shell-Exposure-Checker/2.0 (+https://php2shell.fyi/about; passive, one GET) - Requests come from Cloudflare Workers. If your site is behind Cloudflare, the requests also carry the header
CF-Worker: php2shell.fyi. - The checker sets only these request headers:
User-Agent,Accept: text/htmlandAccept-Encoding: identity. Cloudflare adds theHostheader and, for sites behind Cloudflare, theCF-Workerheader above.
How often
- Each host at most once per 10 minutes, for all users together.
example.comandwww.example.comshare this limit. - Each user: 3 checks at a time, 10 checks per minute, 300 checks per day.
- Every check needs a new Cloudflare Turnstile solve and a confirmation that the user owns the site or has permission to check it.
Active scan
- It runs only when a user presses Run active scan and confirms that they own the site or are authorized to test it. It never starts on its own, after a normal check or on a retry.
- It comes from our own scanner server, not from Cloudflare Workers. User-Agent:
PHP2Shell-Private-Scanner/1.0 (+https://php2shell.fyi/about) - It sends a few
POSTrequests with multipart bodies, one after another, built to trigger the flaw. Each request has a 5-second timeout, and the scan stops after 30 seconds. - These requests can use up PHP memory or end a PHP request on your server.
- Each host, and each of its IP addresses, gets at most one active scan per 10 minutes. Each user can run one active scan at a time and 20 per day. Every scan needs a new Turnstile solve.
- The result is an indicator, never a confirmation: the user sees a status such as Potential issue or No signal detected, not the raw responses of your server.
Opt out
If your site is behind Cloudflare, add a WAF custom rule with this expression and the action Block:
(cf.worker.upstream_zone eq "php2shell.fyi")
That rule covers the normal check. To block the active scan too, or on other servers and WAFs, block both User-Agents. nginx example:
if ($http_user_agent ~* "PHP2Shell-(Exposure-Checker|Private-Scanner)") { return 403; }
Apache example (mod_rewrite):
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} PHP2Shell-(Exposure-Checker|Private-Scanner) [NC]
RewriteRule ^ - [F]
A blocked check gives the user no verdict about your site.
What it reads and shows
- The HTTP status, a short allowlist of response headers (for example
X-Powered-By), cookie names (never values), and up to 256 KiB of HTML, scanned for product markers. - The page body is discarded after the scan. The user sees only derived signals and two short, sanitised header values.
Privacy
- Submitted URLs and results are not stored, and the checker's own request logs are turned off.
- Cloudflare's firewall in front of the checker keeps its standard security-event record (IP address, user agent, path, country and network) for requests it blocks or rate-limits, for example more than 5 checks in 10 seconds. Cloudflare deletes these records after a limited period set by its plan (at most 30 days). We use them only to investigate abuse. The submitted URL is never part of them.
- For rate limits, the user's IP address (IPv6 shortened to /56) is kept only as a keyed hash in memory, for about one day (deleted within a minute after its 24-hour window ends).
- For the per-site limit, the site's host name is kept only as a keyed hash in memory, for about 10 minutes.
- Usage counters contain no host, URL or IP address.
- Usage counters also store an optional campaign tag from the link the visitor followed (for example
?ref=bsky). It holds no personal data. - For an active scan, the scanner server keeps a keyed hash of the host and of its IP addresses for 10 minutes, for the per-site limit. It does not log URLs or results.
- DNS lookups go to Cloudflare's resolver. Cloudflare Turnstile sees the user's IP address. Target sites see Cloudflare's addresses, not the user's.
Contact
Report abuse or a security problem: security@php2shell.fyi. See also security.txt.
Not affiliated
php2shell.fyi is independent. It is not affiliated with the PHP project, the PHP2Shell researchers or Cloudflare.