Insight
Where Do PHP and Node Actually Run?
PHP2Shell and Node2Shell are both on CISA's list of exploited vulnerabilities. Before you can patch, you need to know where the runtimes are, and the official Docker images hide them from most scans.
CISA has added PHP2Shell and the Brotli decoder flaw behind Node2Shell (CVE-2026-111497) to its Known Exploited Vulnerabilities catalogue. Reports disagree on how reliable the public PHP exploits are. BleepingComputer and The Hacker News have the details.
Either way, the first question is the same: where do we run PHP or Node at all?
That sounds like it should take five minutes. It often doesn’t.
The runtime is the easy thing to miss
Most vulnerability scanning reads one of two lists:
- The operating system’s package list. That’s what
dpkg,rpmorapkknows was installed. - The application’s dependencies. That’s what
package-lock.json,composer.lockand similar lockfiles record.
The runtime itself often appears in neither.
The official php Docker image compiles PHP from source. The official node image unpacks a release tarball. Neither installs the runtime through apt or apk, so it never appears in the OS package list. Your lockfile lists your app’s libraries, not the interpreter that runs them.
The same goes for VMs where someone used nvm, downloaded a tarball into /usr/local, or built PHP by hand years ago.
A scan that only reads those two lists can report a clean image while the runtime inside it is vulnerable.
How to check today
Containers
Grep your Dockerfiles for FROM node and FROM php. Don’t stop at your own Dockerfiles: if your images build on an internal base image, check what that one is built FROM too.
The official images record the version in an environment variable, so you can read it without running anything:
docker image inspect --format '{{.Config.Env}}' <image>
Look for NODE_VERSION or PHP_VERSION.
For images already running, check the image digest the orchestrator actually pulled, not the tag in the manifest. Tags move.
Virtual machines
On each host:
which -a node php
node --version
php --version
Then look in the places package managers don’t track: ~/.nvm for every user, /usr/local/bin and /opt.
Prioritise by reach
Once you have the list, mark which of those hosts or services the internet can reach. Patch those first, using the fixed versions in the vendor advisories, then work inwards.
Why this keeps happening
Every runtime packaged outside the OS package manager creates the same blind spot. It isn’t specific to PHP or Node. Python, Java and Go binaries built into images can hide the same way.
A software inventory is only as good as the places it looks. If a question like “where does PHP run?” takes days to answer, the gap isn’t in the scanner’s CVE data. It’s in what the scanner can see.