php2shell: Auditing AI-Generated PHP for RCE Vulnerabilities

By Mihir Pipermitwala · 10 min read

⚡ TL;DR

php2shell (CVE-2026-109618/109619) made pre-auth RCE a PHP-wide problem. Run this 7-step grep and checklist routine to audit AI-generated PHP before deploy.

php2shell: Auditing AI-Generated PHP for RCE Vulnerabilities

On 21 October 2026, the PHP project shipped emergency security releases for two core-engine bugs the industry now calls php2shell. AI tooling found them, they enable unauthenticated remote code execution, and they touch every PHP release of the past decade. Patching the engine closes that hole. It doesn’t do anything about the AI-generated PHP sitting in your repo, quietly interpolating request data into shell commands. Here’s the audit routine you’d run before your next deploy, plus the context that explains why this class of bug got a name of its own.

  • Two memory-safety bugs, CVE-2026-109618 and CVE-2026-109619, enable unauthenticated RCE on PHP releases dating back to 5.4; CVSS tops out at 9.2 (Wiz, October 2026).
  • PHP powers roughly 70% of all websites, and a plain “Hello World” app on a vulnerable version was exploitable because the bugs live below the application layer (Wiz, October 2026).
  • As of 4 November 2026, NCSC-NL tracked 948 PHP-dependent products with 215 still vulnerable and 93 under investigation (NCSC-NL, November 2026).
  • Cloudflare deployed 7 WAF managed rules against known exploit attempts by default, even on its Free plan (Cloudflare, October 2026).

A terminal running a grep-based security audit of AI-generated PHP code hunting for remote code execution sinks

Contents

What Is the php2shell Vulnerability, Really?

php2shell is the shorthand name for two critical vulnerabilities in the PHP core itself, disclosed and patched on 21 October 2026: CVE-2026-109618 and CVE-2026-109619 (NCSC-NL, November 2026). Both are memory-safety flaws. One chain corrupts memory during request cleanup after an out-of-memory error; the other reuses stale request-owned state on a later request handled by the same worker (Wiz, October 2026). A related session-upload-progress issue rounds out the family.

What makes this nastier than a typical CVE: exploitation sits below your application code. Wiz demonstrated pre-authentication RCE on WordPress, Drupal, and Joomla, plus application-agnostic memory disclosure that can leak passwords, tokens, API keys, and certificates. That’s why IEEE Spectrum treated php2shell as a landmark moment for AI in cybersecurity rather than another patch Tuesday.

The AI angle is real, just not the one most people assume. Wiz Research used AI tooling to find and weaponize the bugs; their writeup claims a single researcher did in one week what a world-class team would have needed months to do (Wiz, October 2026). Datadog Security Labs published parallel detection and remediation guidance the same day, and Akamai connected exploitation campaigns to the disclosure within days.

The fixed releases are 8.5.12, 8.4.27, 8.3.36, and 8.2.35, with minimal source backports for PHP 7.4, 8.0, and 8.1 (NCSC-NL, November 2026). Per Wiz, applying the update remains the only complete remediation. Everything else on this page is defense in depth.

Why Does AI-Generated PHP Amplify RCE Risk?

Once the engine is patched, the application layer is your remaining RCE surface, and it has grown fast. Most teams now accept substantial PHP diffs written by coding assistants, and assistants have a specific failure mode: they optimize for “make it work now.”

  • Need a thumbnail? exec("convert $file ...") works on the first try, so it ships.
  • Models lean on training data full of decade-old snippets that use eval() and unserialize() without a second thought.
  • Output is confident and syntactically clean, which lowers review scrutiny per line.
  • Volume compounds it: more generated code means more shell sinks landing per sprint, with less human attention on each one.

I’m not claiming every assistant output is a landmine. The base-rate argument is enough: when code production accelerates and per-line review shrinks, dangerous constructs reach main more often. PHP command injection is one of the oldest bug classes in the language precisely because the shell-execution functions are so convenient. The audit routine below exists to restore the scrutiny that volume removed.

Which Constructs Should You Grep For First?

Start with the sinks. These are the constructs that execute something or pull in something executable.

ConstructWhy it’s dangerousGrep pattern
exec, system, shell_exec, passthru, proc_open, popenRuns a shell command\b(exec|system|shell_exec|passthru|proc_open|popen)\s*\(
BackticksAlias for shell_execBacktick characters with interpolation
eval, assertExecutes a string as PHP\b(eval|assert)\s*\(
unserialize on request dataObject injection via POP gadget chains\bunserialize\s*\(
include/require with variablesLocal or remote file inclusion\b(include|require)(_once)?\s*\(?\s*\$
preg_replace with /eCode execution on PHP < 7preg_replace.*['"].*/e
create_function, call_user_func with inputDynamic function invocation\b(create_function|call_user_func(_array)?)\s*\(

Copy-paste battery for a quick first pass:

Copy
# 1. Shell execution sinks
grep -rnE '\b(exec|system|shell_exec|passthru|proc_open|popen)\s*\(' app/ src/

# 2. eval and friends
grep -rnE '\b(eval|assert)\s*\(' app/ src/

# 3. unserialize fed straight from request data
grep -rnE 'unserialize\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)' app/ src/

# 4. Variable include/require (file inclusion candidates)
grep -rnE '\b(include|require)(_once)?\s*\(?\s*\$' app/ src/

# 5. Backtick execution
grep -rn '`' app/ src/

A hit is a sink, not proof of exploitability. Each one needs a single question answered: can attacker-controlled request data reach the argument, directly or through a config value the attacker influences? If yes, it’s a finding. If it’s fed only from a hardcoded constant, log it and move on.

What Does Vulnerable vs. Fixed PHP Look Like?

Here’s the pattern I’d expect an assistant to produce when you ask for “resize uploaded images.” It works. That’s the problem.

Copy
// Vulnerable: request data interpolated straight into a shell command.
$format = $_GET['format'] ?? 'png';
$file   = $_GET['file'] ?? 'upload.png';

exec("convert uploads/{$file} -resize 800x600 uploads/thumb.{$format}", $out, $code);

if ($code !== 0) {
    throw new RuntimeException("Conversion failed for {$file}");
}

A request like ?file=x.png;cat .env makes the shell run two commands. The attacker reads your secrets, drops a webshell next to the uploads directory, and moves laterally from there.

Copy
// Fixed: no shell, allowlisted inputs, basename-truncated path.
$format = in_array($_GET['format'] ?? 'png', ['png', 'jpg', 'webp'], true)
    ? $_GET['format']
    : 'png';
$file = basename($_GET['file'] ?? 'upload.png');

if (!is_file(__DIR__ . '/uploads/' . $file)) {
    throw new InvalidArgumentException('Unknown file');
}

// First choice: skip the shell entirely with a library.
$imagick = new Imagick(__DIR__ . '/uploads/' . $file);
$imagick->resizeImage(800, 600, Imagick::FILTER_LANCZOS, 1);
$imagick->writeImage(__DIR__ . "/uploads/thumb.{$format}");

If a binary call is genuinely unavoidable, wrap every dynamic argument in escapeshellarg(), truncate paths with basename(), and allowlist the values before they get anywhere near exec(). The fixed version’s hierarchy matters: removing the shell beats escaping the shell. Escaping is one upstream refactor away from disappearing.

Can Cloudflare-Style WAF Protections Buy You Time?

Partially. Cloudflare deployed default protections against the two php2shell CVEs ahead of public disclosure, with 7 managed rules covering known exploit attempts available even on the Free plan (Cloudflare, October 2026). AWS shipped parallel managed rules for PHP workloads, and Datadog Security Labs published detection queries alongside the CDN vendors.

The detection signals published at disclosure are worth wiring into your own alerting: unusual multipart requests followed by memory-limit errors, repeated HTTP 500s, oddly large or malformed PHPSESSID cookies, and unexplained PHP worker churn (Wiz, October 2026).

Limits matter, though. php2shell exploits primitives below the application layer, so generic WAF signatures don’t reliably match every variant, and the vendor guidance is explicit that rules are interim mitigation. A WAF also does nothing for application-level command injection in generated code, though it will catch the crudest ;cat .env payloads. Enable the rules as a seatbelt while you patch. Never instead of patching.

What Goes on Your Pre-Deploy Checklist?

  1. Confirm production runs 8.5.12, 8.4.27, 8.3.36, or 8.2.35, or a backported 7.4/8.0/8.1 build (NCSC-NL, November 2026).
  2. Set session.upload_progress.enabled=0 until you’re past the next bugfix release (NCSC-NL, November 2026).
  3. Run the grep battery above and ticket every sink with a “can request data reach this?” verdict.
  4. Review AI-generated PRs line by line for shell calls, eval, unserialize on request data, and variable includes.
  5. Turn on your WAF’s php2shell managed rules and confirm they’re active, not just available.
  6. Alert on the multipart-plus-memory-limit and worker-churn signals (Wiz, October 2026).
  7. Audit third-party PHP images and appliances separately. NCSC-NL tracked 948 products, and 215 were still vulnerable as of 4 November 2026.

FAQ

Is php2shell a single CVE?

No. It’s two core PHP bugs, CVE-2026-109618 and CVE-2026-109619, plus a related session-upload-progress issue. All are memory-safety flaws enabling unauthenticated RCE or memory disclosure across PHP 5.4 through 8.5.

Did AI write the vulnerable code?

Not in this case. The bugs live in the PHP engine, not in anyone’s generated application code. AI tooling found and weaponized them. Separately, AI assistants do reintroduce classic application-level injection patterns, which the grep routine catches.

Can I skip patching if my WAF rules are enabled?

No. Vendors treat WAF rules as interim mitigation, and applying the 21 October 2026 PHP security release is the only complete remediation. Managed rules can miss exploit variants; the patch eliminates all known ones at the engine level.

Which PHP versions are safe?

8.5.12, 8.4.27, 8.3.36, or 8.2.35, all released 21 October 2026. If you’re pinned to 7.4, 8.0, or 8.1, use the minimal source backports NCSC-NL’s repository links to, and keep interim mitigations active.

How often should I rerun the audit?

Every deploy, honestly, for AI-generated diffs, since each PR is new attack surface. Run the full-codebase grep battery quarterly, or whenever a named class like php2shell shows what the ecosystem is actively being exploited for.

The Verdict

  1. Patch first. The engine fix is the only complete remediation for php2shell, and unpatched PHP 5.4–8.5 hosts are pre-auth RCE with a CVSS of 9.2.
  2. Assume generated code contains sinks. The grep battery takes minutes, and every hit it surfaces needs a one-question triage.
  3. Prefer removing the shell over escaping it. Imagick beats exec("convert ...") on every axis, including the one where refactors stop breaking your escaping.
  4. Layer the WAF, don’t lean on it. Cloudflare’s 7 default rules and the published detection signals buy you time, not safety.
  5. Audit the edges too. NCSC-NL’s tracking shows the slowest-moving part of this vulnerability class is third-party appliances and images, not your own app.

If this reads like familiar ground, it should. The core lesson matches what I argued across my three-part series on securing AI agents: why the prompt-injection analogy holds, how defense in depth and input validation actually work in code, and what production hardening and monitoring look like when the checklist is real. AI accelerates both sides of security. The audit routine is how you keep your side of the acceleration.

Mihir Pipermitwala

Written by Mihir Pipermitwala

Senior Full Stack Consultant & Mobile Engineering Specialist building user-focused applications in healthcare with Flutter, Dart and React Native. I write about what I actually build and test — every tutorial here comes from real project work.

More about Mihir →
Scroll down to load comments...
Related Blogs
Weight-Space Programming: Can LLMs Really Edit Model Weights?

Weight-Space Programming: Can LLMs Really Edit Model Weights?

GPT-6 Astra reportedly edited 0.016% of Qwen's weights and tripled its math score. Here's what the teardown and laptop replication actually showed.

AI MLAI TOOLSON DEVICE LLM

November 10, 2026

Prompt Injection Is the New SQL Injection — Part 3: Production Hardening, Monitoring, and the OWASP 2026 Checklist

Prompt Injection Is the New SQL Injection — Part 3: Production Hardening, Monitoring, and the OWASP 2026 Checklist

Part 3 of a 3-part series. Secure AI agents in production — egress filtering against data exfiltration, canary tokens, audit logging, red-teaming in CI/CD, MCP security, and the OWASP 2026 agentic checklist.

AI TOOLSSECURITYLLMAI AGENTSDEVELOPER TOOLS

November 09, 2026

php2shell: Auditing AI-Generated PHP for RCE Vulnerabilities

php2shell: Auditing AI-Generated PHP for RCE Vulnerabilities

php2shell (CVE-2026-109618/109619) made pre-auth RCE a PHP-wide problem. Run this 7-step grep and checklist routine to audit AI-generated PHP before deploy.

SECURITYPHPAI TOOLSDEVELOPER TOOLS

November 08, 2026

Prompt Injection Is the New SQL Injection — Part 2: Defense in Depth, Input Boundaries, and Tool Validation

Prompt Injection Is the New SQL Injection — Part 2: Defense in Depth, Input Boundaries, and Tool Validation

Part 2 of a 3-part series. Build a four-layer defense against prompt injection in Python — input sanitization, contextual isolation, strict tool argument validation with Pydantic, and human-in-the-loop gates.

AI TOOLSSECURITYLLMAI AGENTSDEVELOPER TOOLS

November 07, 2026

Related Recommended Services
Visual Studio Code for the Web

Visual Studio Code for the Web

Build with Visual Studio Code, anywhere, anytime, in your browser.

IDEVISUAL STUDIOVISUAL STUDIO CODEWEB
Renovate | Automated Dependency Updates

Renovate | Automated Dependency Updates

Renovate Bot keeps source code dependencies up-to-date using automated Pull Requests.

AUTOMATED DEPENDENCY UPDATESBUNDLERCOMPOSERGITHUBGO MODULES
Best XML Formatter and XML Beautifier

Best XML Formatter and XML Beautifier

Online XML Formatter will format xml data, helps to validate, and works as XML Converter. Save and Share XML.

XMLXML BEAUTIFIERXML CONVERTERXML FORMATXML FORMATTER
Kubecost | Kubernetes cost monitoring and management

Kubecost | Kubernetes cost monitoring and management

Kubecost started in early 2019 as an open-source tool to give developers visibility into Kubernetes spend. We maintain a deep commitment to building and supporting dedicated solutions for the open source community.

CLOUDKUBECOSTKUBERNETESOPEN SOURCESELF HOSTED
Related Recommended Stories
How GitHub reduced testing time for iOS apps with new runner features

How GitHub reduced testing time for iOS apps with new runner features

Learn how GitHub used macOS and Apple Silicon runners for GitHub Actions to build, test, and deploy our iOS app faster.

IOSGITHUBTESTINGRUNNER
5 ways to transform your workflow using GitHub Copilot and MCP

5 ways to transform your workflow using GitHub Copilot and MCP

Learn how to streamline your development workflow with five different MCP use cases.

AGENT MODECODING AGENTCOPILOTFIGMAGITHUB
One weird trick for powerful Git aliases

One weird trick for powerful Git aliases

Advanced Git Aliases

ALIASALIAS TEMPLATEATLASSIANBITBUCKETGIT
Awesome Python

Awesome Python

An opinionated list of awesome Python frameworks, libraries, software and resources

AWESOMEAWESOME PYTHONCOLLECTIONSGITHUBPYTHON
Related Recommended Tools
Find out what websites are built with - Wappalyzer

Find out what websites are built with - Wappalyzer

Find out the technology stack of any website. Create lists of websites and contacts by the technologies they use.

ADD ONSANALYTICSAPP STOREAPPLEBOOKING
Sourcetree | Free Git GUI for Mac and Windows

Sourcetree | Free Git GUI for Mac and Windows

A Git GUI that offers a visual representation of your repositories. Sourcetree is a free Git client for Windows and Mac.

GITGITHUBGITLABATLASSIANBITBUCKET
Related Recommended Videos