Skip to content

feat: PHP2Shell exposure check, PHP worker crash alert, scan-finding dedup fix - #13

Merged
vsilent merged 2 commits into
mainfrom
feature/php2shell-check
Oct 31, 2026
Merged

vsilent merged 2 commits into
mainfrom
feature/php2shell-check

Conversation

@vsilent

@vsilent vsilent commented Oct 31, 2026

Copy link
Copy Markdown

What

PHP2Shell (CVE-2026-109618, CVE-2026-109619) is unauthenticated RCE in the PHP interpreter. The fix is upgrading PHP; Stackdog cannot patch it and does not detect the exploit request. This PR adds what Stackdog can do about it.

  • vuln.php2shell (src/detectors/php2shell.rs). Each pass reads the PHP version on the host and in running containers, and flags builds older than 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12, or any 8.1 and older.

    • Version sources: the dpkg/apk package database (containers through MergedDir), and PHP_VERSION from official images (docker-library Dockerfile-linux.template:224).
    • Upstream builds get a Critical alert; distribution packages get a Medium "check your vendor" alert, since backports keep the version number.
    • Only core packages are read: php8.x-common and php8x-common/php8x. The php meta-package and PECL extensions carry their own numbering.
    • Package databases are cached by mtime/size. STACKDOG_PHP_VERSION_CHECK_ENABLED=false turns the check off.
  • php.worker-crash: alerts when 3+ php-fpm or Apache workers die on SIGSEGV/SIGBUS/SIGABRT/SIGILL in one log source within one pass. Log formats come from php-src fpm_children.c:269,308 and httpd os/unix/unixd.c:439.

  • Neither finding names a client, so both are on the explicit never-ban list.

  • Dedup fix (src/sniff/reporter.rs): scan findings have no log source, so all findings of one detector shared one key and only the first per pass alerted. This silently dropped:

    • a second exposed install;
    • a second new shell file;
    • a second integrity change.

    Scan findings now key on sample_line (a path, container, or package and version). Log findings keep the detector-only key, because their sample is a timestamped log line.

  • Docs: README, CHANGELOG, .env.sample, a website PHP2Shell section, the docs settings table, and the quick-start .env.

A code review on the branch found the dedup bug, missed Alpine installs (php83-common without php83), and an overstated crash threshold wording; all three are fixed here.

Verification

  • cargo test: 455 + 8 + 108 passed, 0 failed, 1 ignored. cargo clippy --all-targets -- -D warnings and cargo fmt --check are clean.
  • cd website && npm run build: OK.

Not verified

  • Not run on a real Linux host or real containers. Reading PHP_VERSION through bollard inspect has not been tried against a live container.
  • Guess: exploit attempts against PHP2Shell crash PHP workers. The exploit itself has not been observed.
  • RPM-based hosts (RHEL, Rocky, Alma) are not covered.

🤖 Generated with Claude Code

robotizeit and others added 2 commits October 31, 2026 17:42
…ashes

PHP2Shell (CVE-2026-109618, CVE-2026-109619) is unauthenticated RCE in
the PHP interpreter; the fix is upgrading PHP. Each sniff pass now reads
the PHP version on the host and in running containers (dpkg/apk package
database through MergedDir, and PHP_VERSION from official images) and
alerts on builds older than 8.2.35, 8.3.36, 8.4.27 or 8.5.12
(vuln.php2shell). Upstream builds get a Critical alert. Distribution
packages get a Medium "check your vendor" alert, because backports keep
the old version number. Alpine's version is read from php8x-common, which
every SAPI depends on.

php.worker-crash alerts when 3 or more php-fpm or Apache workers die on
SIGSEGV/SIGBUS/SIGABRT/SIGILL in one log source within one pass. Log
formats are taken from php-src fpm_children.c and httpd unixd.c.

Neither finding names a client, so both are on the never-ban list.

Also fixes alert dedup for scan findings. They had no log source, so
every finding of one detector shared a key and only the first of a pass
alerted. A second exposed install, a second shell file or a second
integrity change was silently dropped. Scan findings now key on their
sample line, which names what was found. Log findings are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vsilent
vsilent merged commit 1ade237 into main Oct 31, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants