Emergency: Patch PHP2Shell (CVE-2026-109618 / CVE-2026-109619) on FusionPBX

Priority: Apply on all internet-facing FusionPBX / FreeSWITCH GUI hosts. Fixed runtime is PHP 8.2.35 (Debian bookworm-security).

Package and helper scripts (install-offline.sh, install-online.sh, verify.sh, rollback.sh) were generated by Renovate bot for this emergency PHP security rollout.

Summary

PHP critical flaws CVE-2026-109618 and CVE-2026-109619 (PHP2Shell) can allow unauthenticated remote code execution on PHP serving web requests. FusionPBX is affected through its PHP-FPM runtime, not through a FusionPBX application bug.

Expertflow validated fix: upgrade the GUI host to PHP 8.2.35 from Debian security, point nginx at php8.2-fpm.sock, keep old PHP packages until verified.

Do you need downtime?

Service

Downtime?

Notes

Voice / FreeSWITCH calls

No planned downtime

PHP-FPM restart does not stop FreeSWITCH.

FusionPBX web GUI / PHP APIs

Brief (typically under 1–2 minutes)

During php-fpm restart + nginx reload. Prefer a low admin-traffic window.

GUI sessions

May need re-login

PHP sessions can reset.

This is not a full platform outage. Calling can continue; only the admin/web UI has a short blip.

Requirements

  • Debian 12 (bookworm), architecture amd64

  • FusionPBX with nginx + PHP-FPM

  • Root access

Choose your path

Customer environment

Use

No internet (air-gapped / closed)

Offline package + install-offline.sh

Has internet to Debian security

install-online.sh (or same commands via apt)

Attachment / package

After unpack, scripts are at:

php82-offline-bundle-*/scripts/install-offline.sh
php82-offline-bundle-*/scripts/install-online.sh
php82-offline-bundle-*/scripts/verify.sh
php82-offline-bundle-*/scripts/rollback.sh

SHA256 of rebuilt package (must match after you re-upload):

cffc7fb2c015844c9d4a98e750a3abdb4a094216cea0defbf5114415161295cd  php82-offline-bundle-8.2.35-deb12-amd64.tar.gz

Path A — Offline (no internet)

  1. Copy the tarball to the customer FusionPBX VM.

  2. As root:

    Bash
    tar -xzf php82-offline-bundle-8.2.35-deb12-amd64.tar.gz
    cd php82-offline-bundle-*/
    ./scripts/install-offline.sh
    ./scripts/verify.sh
    
  3. Confirm GUI login works.

Path B — Online (internet available)

Bash
cd php82-offline-bundle-*/
./scripts/install-online.sh
./scripts/verify.sh

Verify the fix

Bash
php-fpm8.2 -v
# Expect: PHP 8.2.35
zgrep -E 'CVE-2026-109618|CVE-2026-109619' /usr/share/doc/php8.2-fpm/changelog.Debian.gz
ls php82-offline-bundle-*/scripts/rollback.sh
systemctl is-active php8.2-fpm php8.1-fpm
curl -skI https://127.0.0.1/login.php | head

Rollback

Location

Path

Inside the offline package (after unpack)

php82-offline-bundle-*/scripts/rollback.sh

On the host after install (preferred)

/root/php-upgrade-rollback-<timestamp>/scripts/rollback.sh

Confirm it is in the package:

Bash
tar -tzf php82-offline-bundle-8.2.35-deb12-amd64.tar.gz | grep rollback.sh

How to run

Bash
# Preferred after install:
/root/php-upgrade-rollback-<timestamp>/scripts/rollback.sh

# Or from unpacked package:
./scripts/rollback.sh

Do not purge php8.1* until the site is stable for several days.

This rollback.sh was generated by Renovate bot.

Full rollback.sh script
Bash
#!/bin/bash
# Rollback FusionPBX web stack from PHP 8.2 to previous PHP-FPM (usually 8.1).
# Generated by Renovate bot.
set -euo pipefail

if [[ $(id -u) -ne 0 ]]; then
  echo "Run as root"
  exit 1
fi

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [[ -f "$SCRIPT_DIR/../state/prev-fastcgi-sock.txt" ]]; then
  BACKUP_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
else
  BACKUP_ROOT="$(ls -1d /root/php-upgrade-rollback-* 2>/dev/null | sort | tail -1 || true)"
fi

PREV=""
if [[ -n "${BACKUP_ROOT:-}" && -f "$BACKUP_ROOT/state/prev-fastcgi-sock.txt" ]]; then
  PREV=$(cat "$BACKUP_ROOT/state/prev-fastcgi-sock.txt" 2>/dev/null || true)
fi
TARGET="${PREV:-unix:/var/run/php/php8.1-fpm.sock}"

echo "=== Rolling back FusionPBX PHP web stack ==="
echo "Backup root: ${BACKUP_ROOT:-none}"
echo "Restoring nginx fastcgi_pass to: $TARGET"

if [[ -n "${BACKUP_ROOT:-}" && -d "$BACKUP_ROOT/nginx/sites-real" ]]; then
  for f in "$BACKUP_ROOT/nginx/sites-real"/*; do
    [[ -f "$f" ]] || continue
    base=$(basename "$f")
    if [[ -e "/etc/nginx/sites-available/$base" ]]; then
      cp -a "$f" "/etc/nginx/sites-available/$base"
    elif [[ -e "/etc/nginx/sites-enabled/$base" ]]; then
      cp -a "$f" "/etc/nginx/sites-enabled/$base"
    fi
  done
else
  while IFS= read -r f; do
    real=$(readlink -f "$f")
    perl -pi -e "s#unix:/var/run/php/php8\\.2-fpm\\.sock#$TARGET#g; s#unix:/run/php/php8\\.2-fpm\\.sock#$TARGET#g" "$real"
  done < <(find /etc/nginx/sites-enabled -type f -o -type l)
fi

nginx -t

if echo "$TARGET" | grep -q php8.1; then
  systemctl enable php8.1-fpm 2>/dev/null || true
  systemctl start php8.1-fpm
  systemctl stop php8.2-fpm 2>/dev/null || true
elif echo "$TARGET" | grep -q php8.3; then
  systemctl enable php8.3-fpm 2>/dev/null || true
  systemctl start php8.3-fpm
  systemctl stop php8.2-fpm 2>/dev/null || true
fi

systemctl reload nginx
echo "Rollback complete."

Notes

  • If Sury PHP repo GPG key is expired, online install still works from Debian security (-t bookworm-security).

  • Wrong OS/arch (not Debian 12 amd64): do not use this bundle; contact Expertflow for another build.

  • Restrict FusionPBX admin GUI to VPN/allowlist where possible.

  • Helper scripts in this package were generated by Renovate bot.

References

  • PHP security advisory (21 Oct 2026): fixed versions 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35

  • CVEs: CVE-2026-109618, CVE-2026-109619