PHP2Shell 是 PHP 本身的兩個重大漏洞 CVE-2026-109618 與 CVE-2026-109619,可能讓未經驗證的 Web 請求在任何處理 Web 請求的 PHP 安裝上執行程式碼:PHP-FPM、使用 mod_php 的 Apache、php-cgi、FrankenPHP 與 LiteSpeed。兩者都已遭實際利用,並列入 CISA 的 KEV 目錄。修正版本為 PHP 8.5.12、8.4.27、8.3.36 或 8.2.35;PHP 8.1 及更舊版本沒有上游發布的新版。請先升級,再重新建置並重新部署每個帶有 PHP 的容器映像檔,包括仍在執行的舊標籤,以及您已交付給客戶的映像檔。
修補您已知的伺服器是簡單的部分。真正持續存在的暴露,是您遺忘的 PHP:編譯進基礎映像檔的執行環境、去年的映像檔標籤仍在正式環境執行、CI 映像檔,或是帶著終止支援 PHP 交付給客戶的產品。本頁先協助您完成修補,再說明如何找出其餘的部分。
事件經過
| 日期(2026 年) | 事件 | 來源 |
|---|---|---|
| 8 月 11 日與 21 日 | Calif 向 PHP 專案回報這兩個錯誤 | Calif |
| 10 月 17 日 | Amazon 在其蜜罐中觀察到的首次利用嘗試,早於公開揭露 | Amazon Threat Intelligence |
| 10 月 20 日 | PHP 預告將於 10 月 21 日 14:00 UTC 發布資安更新,修正兩個 CVSS 4.0 評分 9.2 的漏洞 | php.net |
| 10 月 21 日 | PHP 發布 8.5.12、8.4.27、8.3.36 與 8.2.35 並公布公告;CVE 記錄公開;NCSC-NL 開設 php2shell 儲存庫 | PHP 公告、NCSC-NL |
| 10 月 21 日 | Docker 官方 php 映像檔更新至已修正版本 | docker-library/php |
| 10 月 21 日 | watchTowr 回報兩個 CVE 都已遭實際利用;CISA 發布警示 | watchTowr、CISA |
| 10 月 22 日 | Searchlight Cyber 發布 php2shell-scanner | GitHub |
| 10 月 23 日 | PHP 建議設定 session.upload_progress.enabled=0,以防範另一個可能性較低的 RCE 途徑 CVE-2026-115560 | php.net |
| 10 月 26 日 | CISA 將兩個 CVE 列入 KEV 目錄,美國聯邦機關的處理期限為 10 月 29 日 | CISA KEV |
PHP2Shell 這個名稱出自 Calif 的分析文章,並廣泛見於業界報導;PHP 自己的公告並未使用這個名稱。CVE 記錄將發現功勞歸於 Calif、Wiz 與 OpenAI。
受影響對象
所有處理 Web 請求的 PHP。PHP 的公告點名 PHP-FPM、使用 mod_php 的 Apache、php-cgi、FrankenPHP 與 LiteSpeed,並指出 mod_php 的風險最高,「已有實證的攻擊手法,未經驗證的請求能在任何應用程式碼執行前觸發攻擊。」由於錯誤位於 PHP 本身,只要底層的 PHP 受影響,建構於 Laravel、Symfony 或 WordPress 的應用程式也同樣暴露於風險中。
| 分支 | 受影響版本 | 修正版本 | 上游支援 |
|---|---|---|---|
| 8.5 | 8.5.12 之前 | 8.5.12 | 積極支援 |
| 8.4 | 8.4.27 之前 | 8.4.27 | 積極支援 |
| 8.3 | 8.3.36 之前 | 8.3.36 | 僅提供資安修正,至 2027 年 12 月 31 日 |
| 8.2 | 8.2.35 之前 | 8.2.35 | 僅提供資安修正,至 2026 年 12 月 31 日 |
| 8.1、8.0、7.4 | 所有版本(依 Calif 與 watchTowr 的回報) | 無新版發布;php-src 中有最小幅度的原始碼回移植 | 終止支援 |
| 7.3 及更舊版本,含 PHP 5 | 所有版本(依 Calif 與 watchTowr 的回報) | 無上游修正 | 終止支援 |
PHP 的公告只列出仍受支援的分支。對於更舊的分支,Calif 回報「我們找到最早受影響的路徑可追溯至 PHP 5.4.0」,watchTowr 則將 PHP 7 與 PHP 5 列為受影響且沒有修正。PHP 表示 8.1 及更舊的分支「已不再獲得 PHP 專案的更新」,但仍為自行從原始碼建置的使用者,發布了 7.4、8.0 與 8.1 的最小幅度原始碼回移植。部分發行版與商業長期支援廠商會為終止支援的分支提供回移植修正,請洽詢您的供應商。如果您正在測試下一個主要版本,同日發布的 PHP 8.6.0 RC4 也包含這些修正。
運作原理
兩個 CVE 都是記憶體安全錯誤,位於 PHP 準備與結束一個請求的流程中,層級低於任何應用程式碼。CVE 記錄將兩者都歸類為釋放後使用(CWE-416),並同時歸類為例外狀況處理不當、存取未初始化指標、未受控的記憶體配置與初始化錯誤(CWE-755、CWE-824、CWE-1325、CWE-1419)。以 PHP 的說法:
- CVE-2026-109618,經由 OOM 損毀的 RCE:「記憶體不足的處理可能在內部請求資料僅部分初始化時中斷 PHP。之後的請求清理可能將這些無效資料當成有效資料處理。」刻意設計成在 PHP 解析時耗盡記憶體的請求本文,就能觸發這種中斷。使用 mod_php 的 Apache 即使在請求啟動失敗時仍會執行清理,因此攻擊在該環境中能於任何應用程式碼執行前成功。至於 PHP-FPM,PHP 的公告表示,原始碼分析顯示它可能受影響,但尚未有人展示完整的 FPM 攻擊手法。
- CVE-2026-109619,經由過時全域狀態的 RCE:「屬於請求的內部狀態,可能在其背後的記憶體釋放後仍然存在。同一個 worker 處理的後續請求,可能在正常初始化將其重設前使用這個過時狀態。」這需要兩個送達同一個 worker 的請求:一個留下該狀態(例如透過致命錯誤),另一個使用它。PHP 的公告已確認 session 上傳進度路徑對 mod_php 與 FPM 有效,PHP 8.5 致命錯誤回溯(backtrace)路徑則對 mod_php 有效。
這就是 PHP 的暫時設定針對記憶體上限、請求本文大小、session 上傳進度與致命錯誤回溯的原因:每項設定各封閉一條通往錯誤的路徑,而非修正錯誤本身。PHP 身為 CNA,依 CVSS 4.0 將兩者都評為 9.2 分。NVD 自行的 CVSS 3.1 評估則是 CVE-2026-109618 為 9.8 分、CVE-2026-109619 為 8.1 分。
如何檢查您是否受影響
先從您已知的主機著手,再找出您建置與交付的所有內容中的 PHP。
在主機或 VM 上,檢查 PHP 回報的版本。也請檢查 Web SAPI,因為 php-fpm 或 Apache 模組可能來自與命令列不同的套件:
php -v
php-fpm -v
發行版套件(Debian、Ubuntu、Alpine、RHEL)常以回移植方式取得修正,而不會換成新的上游版本:例如 Ubuntu 24.04 以 8.3.6-0ubuntu0.24.04.13 提供修正。在這種情況下,只看版本號碼會造成誤判。請列出已安裝的套件,並與您所用發行版資安追蹤頁面上的已修正套件版本比對:
dpkg -l 'php*' | grep '^ii' # Debian, Ubuntu
apk info -v | grep '^php' # Alpine
rpm -qa 'php*' # RHEL, Fedora, Rocky, Alma
在容器映像檔中。 官方 php: 映像檔從原始碼編譯 PHP,因此版本資訊存在於映像檔本身,而非發行版的套件清單中。請直接詢問映像檔:
docker run --rm --entrypoint php php:8.3-fpm -v
若要檢查您實際執行的每個映像檔,請列出它們並逐一詢問。以 Kubernetes 為例:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' \
| sort -u \
| while read -r image; do
version=$(docker run --rm --entrypoint php "$image" -r 'echo PHP_VERSION;' 2>/dev/null)
printf '%s\t%s\n' "${version:-no php}" "$image"
done
以 FROM debian 或 FROM alpine 建置、並透過套件管理工具安裝 PHP 的映像檔,需要在映像檔內執行上述的套件檢查。
在您的儲存庫中,搜尋每一個選用 PHP 的地方:
git grep -nE '^FROM[[:space:]]+(.*/)?php:' -- '*Dockerfile*' '*.dockerfile'
git grep -nE 'php-version|image:.*php' -- .github/workflows '*.yml' '*.yaml'
像 php:8.3.30-fpm 這類固定標籤,在有人修改前都會維持有漏洞的狀態。像 php:8.3-fpm 這類浮動標籤自 10 月 21 日起已以修正版本重新建置,但在此之前建置的映像檔,在您重新建置前仍保留舊的 PHP。php 這個限制條件(位於 composer.json)說明的是程式碼接受哪些版本,而不是實際執行的是哪個版本。
在 CI 中。 建置與測試作業常使用自己的 PHP:php: 服務容器、帶有 php-version 輸入的 setup action,或執行器映像檔。這些不處理正式環境流量,但能顯示您的管線產出哪些映像檔與版本。
對外開放的主機。 Searchlight Cyber 的 php2shell-scanner 會以大型 multipart 請求探測 URL,每個路徑約 29 MiB。請只對您獲授權測試的主機執行。其 README 警告,對於 memory_limit 偏低的已修補 PHP 可能出現誤判;而當 PHP 不揭露版本時,掃描工具也無法分辨已修補與有漏洞的伺服器。請將結果視為線索,而非證據。NCSC-NL 的儲存庫彙整了偵測規則,以及內含 PHP 的產品清單與其狀態。
今天的掃描無法告訴您的事。 今天掃描登錄庫中的映像檔,涵蓋的是您今天會部署的內容。它無法涵蓋您先前交付給客戶的版本、客戶仍在執行的舊標籤,或是您的哪些建置產出了含有漏洞 PHP 的映像檔。要回答這些問題,您需要逐版本記錄每次建置放入了什麼。請參閱我們是否受影響?如何在所有建置中評估新的 CVE。
如何修正,以及尚無法修補時該怎麼做
- 升級至 8.5.12、8.4.27、8.3.36 或 8.2.35,或升級至您所用發行版的已修正套件。若使用 8.1 或更舊版本,請轉移至受支援的分支;PHP 的回移植與廠商建置都只是權宜之計。
- 重新建置每個映像檔,以已修正的基礎映像檔為基礎(重新拉取基礎映像檔,或不使用快取建置),並重新部署。已在執行的映像檔在被取代前會保留舊的 PHP,因此也請重新啟動工作負載。
- 驗證:依下方的檢查清單,針對執行中的容器確認,而不只是新的映像檔。
若您尚無法升級,PHP 的公告列出了一些措施,這些措施「能降低特定攻擊路徑的暴露,但無法讓安裝變得安全」。針對 CVE-2026-109618:
- 「設定
memory_limit=-1,最好採用應用程式無法覆寫的方式,例如在 FPM pool 或 Apache 設定中使用php_admin_value,並確認沒有任何 pool、目錄或應用程式設定重新加回有限的上限。」 - 「不需要上傳檔案的應用程式,請設定
post_max_size = 8M。若必須上傳檔案,請設定post_max_size = 32M。讓upload_max_filesize低於post_max_size。」 - 以容器或 cgroup 的記憶體上限作為可用性的邊界,不要改用
RLIMIT_AS或RLIMIT_DATA,「因為這些可能引發有漏洞的配置失敗。」
針對 CVE-2026-109619:
- 「設定
session.upload_progress.enabled=0並重新啟動每個 worker。請使用php.ini、FPM pool 或在請求解析前就套用的伺服器設定。不要依賴ini_set()或 FPM 的.user.ini。」 - 「在 PHP 8.5 上,設定
fatal_error_backtraces=0並重新啟動每個 worker。」
檢查每個 worker 實際使用的設定:
php-fpm -i | grep -E 'memory_limit|post_max_size|session.upload_progress.enabled'
CISA 的警示更進一步:無法立即更新、或仍在執行 PHP 8.1 及更舊版本的組織,「應將以 PHP 為基礎的系統下線,直到能完成修補或更新為止。」CISA 也建議監看啟動 shell 或下載工具的 PHP worker 程序。
驗證修正
- 詢問執行中的 PHP,而不是您打算部署的映像檔。 在每個執行中的容器內與每台主機上執行
php-fpm -v(或php -v),確認版本為 8.5.12、8.4.27、8.3.36、8.2.35 或更新版本。 - 對於發行版套件,不要只相信版本字串。 Debian、Ubuntu、RHEL 等發行版會將修正回移植到既有版本,因此已修補的 PHP 仍可能顯示 8.3.6:Ubuntu 24.04 的修正版本為
8.3.6-0ubuntu0.24.04.13。請將完整的套件版本與您所用發行版的資安追蹤頁面比對,或在套件的變更記錄中尋找該 CVE,通常會載明。這個陷阱反過來也成立:只比對上游版本號碼的掃描工具,可能會把已回移植修正的套件標記為有漏洞。 - 確認每個工作負載都執行重新建置的映像檔。 標籤改指向已修正的映像檔,並不會改變已拉取舊映像檔的 pod。請將每個容器執行的映像檔摘要(digest)與您建置的摘要比對:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .status.containerStatuses[*]}{.image}{"\t"}{.imageID}{"\n"}{end}{end}'
- 確認每個 worker 都已重新啟動。 PHP-FPM 與 Apache 在重新啟動前會保留已載入的舊程式碼;「檢查是否遭入侵」中的程序檢查會顯示仍在執行舊程式碼的程序。
- 如果您仍依賴暫時設定, 請使用上方的
php-fpm -i指令檢查每個 pool,並在所有環境完成升級前維持這些設定。 - 重新執行盤點:依檢查一節的方法,涵蓋您的登錄庫、CI 映像檔與客戶執行的版本,而不只是正式環境。
檢查是否遭入侵
PHP2Shell 已遭實際利用,Amazon 於 2026 年 10 月 17 日觀察到首次嘗試,比修正早了四天。若對外開放的 PHP 自那時起曾在未套用暫時設定的情況下執行受影響的版本,請進行檢查。
暴露規模有多大。 根據 CybelAngel 的報導,Mallory 於 10 月 20 日公布的 Shodan banner 統計發現,有 224 萬台對外開放的主機顯示使用 PHP;在約 150 萬台顯示版本的主機中,有 883,717 台(59%)執行沒有官方修正的分支。這些是主機數量,而非經確認有漏洞的系統:已回移植修正的套件可能看起來很舊但其實已修補,且約有 74 萬台主機隱藏了版本。
內含 PHP 的設備與產品。 PHP 也在設備、網路裝置、管理介面與廠商產品中執行,而這些可能是您無法自行更新的。截至 2026 年 11 月 9 日,NCSC-NL 的清單追蹤了 968 項此類產品:205 項已修正、215 項有漏洞、93 項調查中、240 項取決於執行環境、214 項不受影響。請另外檢查這些產品,並在廠商更新推出後盡快套用。
確認修正確實在執行。 在主機與 VM 上,於升級前啟動的 PHP-FPM、php-cgi 或 Apache 程序仍執行舊程式碼。此時其記憶體映射會將被取代的執行檔或 libphp 顯示為已刪除。也請將程序啟動時間與升級時間比對:
for pid in $(pgrep -f 'php-fpm|php-cgi|apache2|httpd|frankenphp'); do
grep -qE '(php|libphp)[^/]*\(deleted\)' "/proc/$pid/maps" 2>/dev/null \
&& echo "PID $pid still runs a replaced PHP"
done
ps -o pid,lstart,args -p "$(pgrep -d, -f 'php-fpm|php-cgi|apache2|httpd|frankenphp')"
來自第一手來源的入侵指標:
- 請求: 含有字串
PHP_SESSION_UPLOAD_PROGRESS的表單上傳 POST 請求,這是 Amazon Threat Intelligence 在利用嘗試中觀察到的。Amazon 也列出了來源位址(103.216.220.92、31.223.184.166、37.19.200.5、134.209.159.64、103.114.163.188、95.217.98.37),但註明這些位址屬於共用的匿名化基礎設施:若比對相符,請進行調查,但不要將其視為證據。 - 程序與檔案: 啟動 shell 或下載工具的 PHP worker 程序(CISA,並於 10 月 23 日新增了 Sigma 偵測規則),以及 Web 伺服器上非預期的程序執行或檔案變更(Amazon)。
- 記錄檔: 在 Apache、PHP-FPM、反向代理與服務的記錄檔中,於指令碼執行前重複出現的警告或核心錯誤、致命錯誤與解析錯誤,以及
Maximum execution time exceeded。PHP 的公告補充指出:「記錄檔中沒有錯誤,並不代表安全。」
何時應假設已遭入侵。 如果您發現上述任何指標,或對外開放的伺服器曾在未套用緩解措施的情況下執行受影響的 PHP,且記錄檔無法排除遭利用的可能,請視為已遭入侵。PHP 將影響描述為以 Web worker 帳號身分執行遠端程式碼,而該帳號通常能讀取應用程式的設定與機密。
輪替 worker 能讀取的內容。 包括環境變數與設定檔中的資料庫密碼、API 金鑰與權杖,用於簽署 session 或 cookie 的金鑰(以及以這些金鑰簽署的 session),以及主機可取用的任何雲端憑證。請在主機重建後再輪替,讓新的機密不會存放在已遭入侵的機器上。
重建而非清理。 以已知安全的映像檔取代遭入侵的主機或容器,且不要沿用 worker 能寫入的檔案,例如上傳目錄、快取或產生的程式碼。也不要重複使用在遭入侵主機上產生的映像檔、建置快取或建置產物。
如何告知您的客戶
如果您交付的軟體在 PHP 上執行,客戶一定會詢問。即使尚未掌握所有答案,也請以版本與行動來回覆。以下是可調整使用的回覆範例:
PHP2Shell(CVE-2026-109618、CVE-2026-109619)影響 8.5.12、8.4.27、8.3.36 與 8.2.35 之前的 PHP 版本,以及所有更舊的 PHP 分支。[產品] 的 [x 至 y] 版內含 PHP [版本],因此受影響;於 [日期] 發布的 [z] 版內含 PHP [已修正版本]。請升級至 [z] 版。若無法立即升級,請套用我們公告 [連結] 中的 PHP 設定,並限制對應用程式的網路存取。[產品] 的 [a 至 b] 版不受影響。我們將於 [日期] 前更新本通知。
如果您仍在檢查中,請如實說明,並告知何時會回覆。關於第一份暫時聲明與各種結果的範本,請參閱供應鏈攻擊後如何回覆客戶。
CRACI 如何協助
CRACI 執行您的 GitHub Actions 作業,並在建置時記錄每個作業拉入的內容,包括容器映像檔、apt 與 apk 套件以及 Composer 套件,同時保存每次過去的建置及其 SBOM。當 CVE 公布時,持續重新評估會標記出含有受影響套件的過去建置,讓您看到哪些版本曾暴露於風險、暴露了多久,而不只是今天的掃描結果。政策關卡可以封鎖含有特定 CVE 的建置。
針對這次事件有一項限制:編譯進官方 php: 映像檔的 PHP 是隨映像檔一起進來的,而非以套件下載的形式。CRACI 會記錄每次建置拉取的映像檔參照,因此除了 PHP 套件之外,也請在您的建置中搜尋 php: 標籤。
更多關於建置記錄的內容:建置時 SBOM、Docker 映像檔 SBOM、容器掃描會遺漏什麼、CISA KEV 目錄與 CVE 發布趨勢。其他事件:所有漏洞。
關於這次事件以外的 PHP 安全,請參閱我們的 PHP 安全指南。
來源與更新
第一手來源:
- PHP:2026 年 10 月 21 日的資安公告、2026 年 10 月 23 日的資訊性公告、GHSA-w8hw-w9fx-j79w、GHSA-6wmf-4rv5-p3rp、受支援版本
- CVE 記錄:CVE-2026-109618、CVE-2026-109619
- CISA:2026 年 10 月 21 日的警示、KEV 目錄
- NCSC-NL:php2shell 儲存庫
- NVD:CVE-2026-109618、CVE-2026-109619
- FIRST:EPSS 分數
研究與分析:
- Calif:PHP2Shell,兩個 PHP 遠端漏洞的故事
- Amazon Threat Intelligence
- watchTowr
- Akamai
- CybelAngel
- Searchlight Cyber php2shell-scanner
更新記錄:
- 2026-11-11:在資訊框中新增 NVD 的分數、EPSS、CWE 類別、致謝、最新的安全版本與終止支援日期,新增 PHP 8.6.0 RC4,以及錯誤運作原理、驗證修正與檢查是否遭入侵等章節。
- 2026-11-11:首次發布。