From 62e8520a8d430cd61a043834108362a91a0bbb9e Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Wed, 21 Oct 2026 12:05:18 -0600 Subject: [PATCH] fix: PHP2Shell workaround, upgrade PHP in DDEV web images on workspace start PHP2Shell (CVE-2026-109618/CVE-2026-109619) allows unauthenticated RCE against any PHP serving web requests. Workspaces can share their sites publicly (drupal_site_public, freeform public sharing), so they are exposed. The coder-ddev image itself has no PHP; the vulnerable PHP is in the ddev-webserver image pulled inside each workspace, and no fixed DDEV release exists until v1.25.5. Following https://ddev.com/blog/php2shell-what-ddev-users-need-to-know/, each template now writes .ddev/web-build/Dockerfile.php2shell on every start, which runs `apt-get install --only-upgrade 'php*'` when the web image is built: - drupal-core / drupal-contrib: written next to config.coder.yaml, so the startup `ddev start` rebuilds with fixed PHP. - freeform: written into every project in `ddev list`; takes effect on each project's next `ddev start`/`ddev restart`. Dockerfile.php2shell is added to ~/.gitignore_global (and the image's copy) so it does not appear as untracked in core/contrib clones. Remove these steps after upgrading the image to DDEV v1.25.5. Co-Authored-By: Claude Opus 5.5 --- drupal-contrib/template.tf | 18 ++++++++++++++++++ drupal-core/template.tf | 18 ++++++++++++++++++ freeform/template.tf | 22 ++++++++++++++++++++++ image/scripts/.gitignore_global | 1 + 4 files changed, 59 insertions(+) diff --git a/drupal-contrib/template.tf b/drupal-contrib/template.tf index 31c1656..11b2580 100644 --- a/drupal-contrib/template.tf +++ b/drupal-contrib/template.tf @@ -335,6 +335,13 @@ resource "coder_agent" "main" { grep -qxF 'config.coder.yaml' "$HOME/.gitignore_global" || \ echo 'config.coder.yaml' >> "$HOME/.gitignore_global" fi + # PHP2Shell workaround (written into the project's .ddev/web-build below). + # Outside the if/elif so a fresh copy from an older image also gets it. + # Remove together with the Dockerfile.php2shell step after DDEV v1.25.5. + if [ -f "$HOME/.gitignore_global" ]; then + grep -qxF 'Dockerfile.php2shell' "$HOME/.gitignore_global" || \ + echo 'Dockerfile.php2shell' >> "$HOME/.gitignore_global" + fi if [ -n "$CODER_WORKSPACE_OWNER_NAME" ]; then git config --global user.name "$CODER_WORKSPACE_OWNER_NAME" fi @@ -622,6 +629,17 @@ hooks: - exec-host: 'echo "" && echo " Site: https://drupal-site--$${CODER_WORKSPACE_NAME}--$${CODER_WORKSPACE_OWNER_NAME}.$CODER_DOMAIN" && echo " Mailpit: https://mailpit--$${CODER_WORKSPACE_NAME}--$${CODER_WORKSPACE_OWNER_NAME}.$CODER_DOMAIN" && echo ""' CODER_YAML_EOF + # PHP2Shell (CVE-2026-109618/CVE-2026-109619): upgrade PHP in the web image + # until DDEV v1.25.5 ships a fixed ddev-webserver. Remove after that upgrade. + # https://ddev.com/blog/php2shell-what-ddev-users-need-to-know/ + mkdir -p .ddev/web-build + cat > .ddev/web-build/Dockerfile.php2shell << 'PHP2SHELL_EOF' +# Auto-generated by coder-ddev workspace startup -- do not edit. +# PHP2Shell fix; safe to delete after upgrading to DDEV v1.25.5. +RUN (apt-get update || true) && apt-get install -y --only-upgrade 'php*' +PHP2SHELL_EOF + log_setup "✓ .ddev/web-build/Dockerfile.php2shell written (PHP2Shell fix)" + # For themes, set symlink target path via config.local.yaml if [ "$PROJECT_TYPE" = "theme" ]; then cat > .ddev/config.local.yaml << 'THEME_YAML_EOF' diff --git a/drupal-core/template.tf b/drupal-core/template.tf index 87cbe25..623a461 100644 --- a/drupal-core/template.tf +++ b/drupal-core/template.tf @@ -396,6 +396,13 @@ resource "coder_agent" "main" { grep -qxF 'config.zzz-coder-test-env.yaml' "$HOME/.gitignore_global" || \ echo 'config.zzz-coder-test-env.yaml' >> "$HOME/.gitignore_global" fi + # PHP2Shell workaround (written into the project's .ddev/web-build below). + # Outside the if/elif so a fresh copy from an older image also gets it. + # Remove together with the Dockerfile.php2shell step after DDEV v1.25.5. + if [ -f "$HOME/.gitignore_global" ]; then + grep -qxF 'Dockerfile.php2shell' "$HOME/.gitignore_global" || \ + echo 'Dockerfile.php2shell' >> "$HOME/.gitignore_global" + fi if [ -n "$CODER_WORKSPACE_OWNER_NAME" ]; then git config --global user.name "$CODER_WORKSPACE_OWNER_NAME" fi @@ -711,6 +718,17 @@ hooks: CODER_YAML_EOF log_setup "✓ .ddev/config.coder.yaml written" + # PHP2Shell (CVE-2026-109618/CVE-2026-109619): upgrade PHP in the web image + # until DDEV v1.25.5 ships a fixed ddev-webserver. Remove after that upgrade. + # https://ddev.com/blog/php2shell-what-ddev-users-need-to-know/ + mkdir -p .ddev/web-build + cat > .ddev/web-build/Dockerfile.php2shell << 'PHP2SHELL_EOF' +# Auto-generated by coder-ddev workspace startup -- do not edit. +# PHP2Shell fix; safe to delete after upgrading to DDEV v1.25.5. +RUN (apt-get update || true) && apt-get install -y --only-upgrade 'php*' +PHP2SHELL_EOF + log_setup "✓ .ddev/web-build/Dockerfile.php2shell written (PHP2Shell fix)" + if ddev config --project-type="$DDEV_PROJECT_TYPE" $DDEV_DOCROOT_ARG --project-name="$${CODER_WORKSPACE_NAME}--$${CODER_WORKSPACE_OWNER_NAME}" >> "$SETUP_LOG" 2>&1; then log_setup "✓ DDEV configured (project-type=$DDEV_PROJECT_TYPE)" update_status "✓ DDEV config: Success" diff --git a/freeform/template.tf b/freeform/template.tf index 6efcd8b..76bc52e 100644 --- a/freeform/template.tf +++ b/freeform/template.tf @@ -247,6 +247,13 @@ resource "coder_agent" "main" { grep -qxF 'config.coder.yaml' "$HOME/.gitignore_global" || \ echo 'config.coder.yaml' >> "$HOME/.gitignore_global" fi + # PHP2Shell workaround (written into each project's .ddev/web-build below). + # Outside the if/elif so a fresh copy from an older image also gets it. + # Remove together with the Dockerfile.php2shell step after DDEV v1.25.5. + if [ -f "$HOME/.gitignore_global" ]; then + grep -qxF 'Dockerfile.php2shell' "$HOME/.gitignore_global" || \ + echo 'Dockerfile.php2shell' >> "$HOME/.gitignore_global" + fi mkdir -p ~/.ddev if [ -n "$CODER_WORKSPACE_OWNER_NAME" ]; then git config --global user.name "$CODER_WORKSPACE_OWNER_NAME" @@ -303,6 +310,21 @@ resource "coder_agent" "main" { tail -20 /tmp/ddev-download-images.log || true fi + # PHP2Shell (CVE-2026-109618/CVE-2026-109619): upgrade PHP in every known + # project's web image until DDEV v1.25.5 ships a fixed ddev-webserver. Takes + # effect on each project's next `ddev start`/`ddev restart`. Remove after + # that upgrade. https://ddev.com/blog/php2shell-what-ddev-users-need-to-know/ + ddev list -j 2>/dev/null | jq -r '.raw[]?.approot // empty' 2>/dev/null | while read -r _root; do + [ -d "$_root/.ddev" ] || continue + mkdir -p "$_root/.ddev/web-build" + cat > "$_root/.ddev/web-build/Dockerfile.php2shell" << 'PHP2SHELL_EOF' +# Auto-generated by coder-ddev workspace startup -- do not edit. +# PHP2Shell fix; safe to delete after upgrading to DDEV v1.25.5. +RUN (apt-get update || true) && apt-get install -y --only-upgrade 'php*' +PHP2SHELL_EOF + echo "✓ PHP2Shell fix written: $_root/.ddev/web-build/Dockerfile.php2shell" + done + # Ensure yq and linuxbrew are in PATH for this session export PATH="$PATH:/home/linuxbrew/.linuxbrew/bin" diff --git a/image/scripts/.gitignore_global b/image/scripts/.gitignore_global index 1930893..7bfafcb 100644 --- a/image/scripts/.gitignore_global +++ b/image/scripts/.gitignore_global @@ -1,6 +1,7 @@ # DDEV Coder integration config.coder.yaml config.zzz-coder-test-env.yaml +Dockerfile.php2shell # macOS .DS_Store