PHP2Shell: Lỗ hổng PHP cho phép bất kỳ ai thực thi mã trên máy chủ của bạn (Vá ngay)

Hai lỗ hổng PHP nghiêm trọng, CVE-2026-109618 và CVE-2026-109619, cho phép kẻ tấn công chưa xác thực thực thi mã trên mọi SAPI phục vụ HTTP. Đây là cách kiểm tra máy chủ của bạn, vá lên 8.5.12/8.4.27/8.3.36/8.2.35 và những gì các giải pháp tạm thời thực sự bao phủ.

Ashley Innocent

Ashley Innocent

23 tháng 10 2026

PHP2Shell: Lỗ hổng PHP cho phép bất kỳ ai thực thi mã trên máy chủ của bạn (Vá ngay)

Apidog cho doanh nghiệp

Triển khai tại chỗ

SSO & RBAC

Tuân thủ SOC 2

Khám phá Apidog Enterprise

Vào ngày 21 tháng 10 năm 2026, dự án PHP đã phát hành các bản cập nhật khẩn cấp cho hai lỗi nghiêm trọng cho phép kẻ tấn công chưa xác thực chạy mã trên máy chủ web. Cặp lỗi này được theo dõi với mã CVE-2026-109618 và CVE-2026-109619, mang tên PHP2Shell. Cả hai đều đạt điểm 9.2 theo CVSS v4.0, cả hai đều ảnh hưởng đến mọi cấu hình PHP phục vụ HTTP, và các honeypot của Amazon đã ghi nhận các nỗ lực khai thác vào ngày 17 tháng 10, bốn ngày trước khi bản vá tồn tại.

PHP chạy trên 69,3% các trang web có ngôn ngữ phía máy chủ được xác định (W3Techs). Nếu bạn vận hành một API PHP, một backend Laravel hay Symfony, một trang WordPress, hoặc một container image được đóng gói sẵn PHP, thì đây chính là vấn đề của bạn.

Hướng dẫn này trình bày các lỗi này gây ra điều gì, những phiên bản nào bị ảnh hưởng, cách kiểm tra máy chủ của bạn, các biện pháp giảm thiểu thực sự mang lại điều gì, và cách chứng minh API của bạn vẫn hoạt động sau khi vá.

button

TL;DR

Câu hỏi Trả lời
Đây là gì? Hai lỗi an toàn bộ nhớ trong cơ chế xử lý yêu cầu của PHP, được kết hợp thành thực thi mã từ xa
CVE CVE-2026-109618 (hỏng dữ liệu do hết bộ nhớ), CVE-2026-109619 (trạng thái cũ, use-after-free)
Mức độ nghiêm trọng CVSS v4.0 9.2 cho mỗi lỗi (các ID bị rò rỉ ban đầu ghi 10.0; PHP nói rằng con số đó sai)
Cần xác thực không? Không
Bị ảnh hưởng Mọi SAPI phục vụ HTTP: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, LiteSpeed
Phiên bản đã vá 8.5.12, 8.4.27, 8.3.36, 8.2.35
PHP 8.1 và cũ hơn Không có bản phát hành chính thức; chỉ có bản backport tối thiểu từ mã nguồn cho 7.4, 8.0, 8.1; từ 5.4 đến 7.3 không có gì
Đã bị khai thác chưa? Đã thấy các nỗ lực từ ngày 17 tháng 10 (Amazon), Cloudflare báo cáo các cuộc tấn công sớm
Cách khắc phục Nâng cấp, khởi động lại mọi worker. Các biện pháp tạm thời giảm rủi ro nhưng không bịt kín hoàn toàn

PHP2Shell thực chất là gì

Cả hai lỗi đều có chung một nguyên nhân gốc: PHP có thể để lại bộ nhớ ở trạng thái hỏng khi một yêu cầu kết thúc bất thường, và đoạn mã dọn dẹp sau đó lại tin tưởng vào trạng thái hỏng đó.

CVE-2026-109618: hỏng dữ liệu do hết bộ nhớ trong quá trình khởi động yêu cầu. Khi PHP phân tích dữ liệu form vào $_POST, đoạn mã bảng băm của Zend engine tăng bộ đếm entry của nó trước khi cấp phát khóa mới. Phân tích của Datadog truy vết vấn đề đến _zend_hash_str_add_or_update_i() trong zend_hash.c. Nếu việc cấp phát đó vượt quá memory_limit, PHP ném ra lỗi fatal và bỏ dở thao tác chèn. Bộ đếm lúc này đã tính cả một bucket chưa từng được thiết lập. Khi tắt, PHP hủy $_POST và coi mọi bucket đã được đếm là thật.

Điều mà các đội API nên lo lắng: việc này xảy ra khi PHP vẫn đang phân tích phần thân yêu cầu, trước khi một dòng mã nào của bạn chạy. Middleware xác thực, bộ giới hạn tốc độ và khâu kiểm tra dữ liệu đầu vào của bạn không bao giờ thấy yêu cầu đó. Datadog đã tái hiện nó bằng một phần thân application/x-www-form-urlencoded thông thường, chứ không phải tải tệp lên.

CVE-2026-109619: trạng thái toàn cục cũ tồn tại qua các yêu cầu. PHP giữ một số trạng thái ở phạm vi worker trỏ đến bộ nhớ của từng yêu cầu. Nếu một lỗi fatal cắt ngang quá trình thiết lập lại trạng thái đó, hoặc một chẩn đoán lúc tắt muộn màng tạo lại nó sau khi dọn dẹp, thì yêu cầu tiếp theo trên cùng worker đó sẽ đọc vùng bộ nhớ đã được giải phóng. PHP xác nhận có hai con đường:

Nhóm bảo mật PHP đánh giá mod_php là rủi ro cao nhất, vì khai thác được chứng minh chỉ cần một yêu cầu chưa xác thực là kích hoạt trước khi bất kỳ mã ứng dụng nào được tải.

Ai đã tìm ra (và vì sao AI lại lên mặt báo)

Các lỗi này bắt nguồn từ đoạn mã được đưa vào từ PHP 5.4.0, nghĩa là chúng đã nằm trong mã nguồn hơn một thập kỷ. PHP Foundation ghi nhận công lao cho Calif, OpenAI và Wiz.

Các bài báo từ Decrypt và The Next Web cho biết nhà nghiên cứu Ryan Austin của Calif đã tìm ra các lỗ hổng vào tháng 8 trong một cuộc kiểm tra mã nguồn có sự hỗ trợ của GPT-5.6 Sol từ OpenAI. OpenAI nói rằng nhóm của họ đã tìm ra một phiên bản đầy đủ hơn vào tháng 9 trong khuôn khổ công việc “Patch the Planet”. Wiz nói rằng họ tự tìm ra cả hai lỗi bằng Gemini 4 Argon, Wiz Atlas và GPT-5.6 Sol. Công lao còn tranh cãi; nhưng bài học thì không. Các cuộc kiểm tra có AI hỗ trợ giờ đây đang tìm ra những lỗi bộ nhớ đã tồn tại hàng thập kỷ trong hạ tầng cốt lõi, và kẻ tấn công cũng có những mô hình tương tự.

Dòng thời gian: vì sao bản vá đến sớm một ngày

Ngày (2026) Diễn biến
Tháng 8 đến tháng 9 Calif, OpenAI và Wiz báo cáo các lỗi một cách riêng tư
17 tháng 10 Honeypot MadPot của Amazon ghi nhận một nỗ lực khai thác
20 tháng 10 Các ID CVE bị rò rỉ trên Hacker News và mạng xã hội; PHP đăng thông báo trước; CERT-EU ra khuyến cáo 2026-018
21 tháng 10, 14:00 UTC PHP phát hành bản vá, được đẩy sớm từ ngày 22 tháng 10 sau vụ rò rỉ; CISA công bố cảnh báo; Cloudflare báo cáo các cuộc tấn công sớm
22 tháng 10 Cả hai CVE vẫn chưa có trong danh mục KEV của CISA

Amazon khuyến nghị điều tra từ ngày 17 tháng 10 (FAQ của Tenable theo dõi toàn bộ dòng thời gian), chứ không phải từ ngày công bố. Khi phát hành, nhóm PHP cho biết họ đã kiểm tra mã proof-of-concept xuất hiện sau vụ rò rỉ và không tìm thấy khai thác nào hoạt động được. watchTowr sau đó nói rằng họ đã tái hiện được cả hai lỗi. Hãy coi mọi repo “PoC” bạn tìm thấy là đáng ngờ: mã khai thác chưa được kiểm chứng thường kèm theo malware.

Bạn có bị ảnh hưởng không? Kiểm tra trong năm phút

1. Kiểm tra runtime đang phục vụ lưu lượng, không phải laptop của bạn. Tệp nhị phân CLI có thể khác về phiên bản và cấu hình so với module FPM hoặc Apache.

# On the server or inside the running container
php -v
php-fpm -v
# Apache mod_php: check the loaded module version
apachectl -M 2>/dev/null | grep -i php

Hoặc công khai nó một lần từ một route được bảo vệ rồi xóa đi:

<?php echo PHP_VERSION, ' ', PHP_SAPI;

2. So sánh với các phiên bản đã vá.

Nhánh Bị ảnh hưởng Được vá trong
8.5 < 8.5.12 8.5.12
8.4 < 8.4.27 8.4.27
8.3 < 8.3.36 8.3.36
8.2 < 8.2.35 8.2.35
7.4 đến 8.1 Tất cả Chỉ có bản backport từ mã nguồn, hoặc LTS của nhà cung cấp
5.4 đến 7.3 Tất cả Không có bản vá

Debian, Ubuntu, Red Hat và các bản phân phối khác thường backport bản vá mà không thay đổi chuỗi phiên bản gốc. Nếu php -v hiển thị số phiên bản cũ hơn, hãy đọc khuyến cáo của bản phân phối bạn dùng trước khi hoảng.

3. Kiểm kê PHP ẩn. Các container được build FROM php:8.3-fpm từ nhiều tháng trước, các thiết bị của nhà cung cấp, các bản build tự biên dịch, các bảng quản trị trên những subdomain bị lãng quên. Cisco đã mở một khuyến cáo để kiểm tra dòng sản phẩm của chính mình. Shodan đếm được hơn 1,9 triệu máy chủ PHP hướng ra internet; một nhà nghiên cứu ước tính 1,3 triệu hoặc hơn có thể đang bị ảnh hưởng.

Cách vá

# Debian / Ubuntu (Ondřej Surý PPA or distro packages)
sudo apt update && sudo apt install --only-upgrade 'php8.*'

# RHEL / Rocky / Alma with Remi
sudo dnf upgrade 'php*'

# Official Docker image: rebuild on a fixed tag
docker pull php:8.4.27-fpm
docker build --pull -t my-api:patched .

Sau đó làm bước mà hầu hết các đội bỏ qua: khởi động lại hoặc thay thế mọi worker PHP. Một pool FPM đang chạy vẫn giữ tệp nhị phân cũ trong bộ nhớ. Khởi động lại php-fpm, tải lại Apache, và triển khai lại (roll) mọi container. CVE-2026-109619 liên quan đến trạng thái tồn tại qua các yêu cầu bên trong một worker, nên một worker chưa được khởi động lại vẫn còn dễ bị tấn công.

Trên 8.1 hoặc cũ hơn, bạn có ba lựa chọn: gói LTS của nhà cung cấp, build từ bản backport mã nguồn của PHP, hoặc nâng cấp lên 8.2+. CISA khuyến nghị đưa các hệ thống PHP không thể vá được ra khỏi mạng, và NCSC của Anh cùng FBI cũng nói như vậy.

Các biện pháp giảm thiểu nếu hôm nay bạn không thể vá

Những biện pháp này chỉ câu giờ. Gina Peter Banyard thuộc nhóm core của PHP nói với BleepingComputer rằng không biện pháp giảm thiểu nào chặn được hoàn toàn các cuộc tấn công.

Đối với CVE-2026-109618:

Đối với CVE-2026-109619:

Ở lớp biên: Cloudflare đã triển khai các quy tắc WAF cho những vector đã biết trên mọi gói, kể cả gói miễn phí. CTO của họ gọi đó là các biện pháp tạm thời.

Sau bất kỳ thay đổi nào trong php.ini, hãy khởi động lại mọi worker, nếu không thay đổi đó không có hiệu lực.

Dấu hiệu bạn đã bị tấn công

Hướng dẫn phát hiện của Datadog quy về bốn tín hiệu:

Đừng tin vào mã trạng thái. Bản khai thác tinh chỉnh của Datadog trả về HTTP 200 và worker vẫn tiếp tục chạy. Hãy tìm trong log ngược về ngày 17 tháng 10.

Chứng minh API của bạn vẫn hoạt động sau khi vá: để agent của bạn chạy kiểm thử

Vá PHP trên môi trường production dưới áp lực là cách bạn phát hiện ra rằng một bản nâng phiên bản nhỏ đã làm thay đổi điều gì đó. Trước và sau khi triển khai bản sửa, hãy chạy bộ kiểm thử API của bạn trên môi trường staging, và để coding agent của bạn thực hiện việc đó với Apidog CLI.

Thiết lập (một lần):

npm install -g apidog-cli
apidog auth login --with-token <your-access-token>
apidog test-suite list --project <projectId>

Một câu lệnh cho Claude Code, Codex hoặc Cursor:

Chúng tôi vừa nâng cấp PHP lên 8.4.27 trên staging để xử lý PHP2Shell. Hãy dùng Apidog CLI để chạy bộ kiểm thử hồi quy của chúng tôi trên môi trường staging, tạo báo cáo HTML và JUnit, và tóm tắt các endpoint bị lỗi. Sau đó xác nhận rằng một POST với phần thân vượt quá client_max_body_size của nginx sẽ bị từ chối với mã 413 tại proxy thay vì đi tới PHP.

Những gì agent sẽ chạy:

apidog test-suite run <testSuiteId> --project <projectId> -e <stagingEnvId>

apidog run --test-suite <testSuiteId> --project <projectId> -e <stagingEnvId> \
  -r cli,html,junit --out-dir ./php2shell-reports --upload-report

-r chọn các trình báo cáo, --out-dir đặt nơi báo cáo được lưu, và --upload-report đẩy lên một bản tóm tắt mà bạn có thể mở trong ứng dụng Apidog. Thêm --notification-failed-event <targetId> để chỉ ping nhóm của bạn khi có sự cố. Hãy đưa nguyên dòng apidog run đó vào CI để mọi image PHP được build lại đều được kiểm thử trước khi phát hành. Hướng dẫn thiết lập Claude Code và bài hướng dẫn quy trình CI/CD trình bày chi tiết cả hai.

Hãy chạy bộ kiểm thử một lần trên phiên bản cũ để lấy đường cơ sở, một lần sau khi nâng cấp, rồi so sánh. Nếu một bài kiểm thử mà bạn không hề nghĩ sẽ thất bại lại thất bại, bạn sẽ biết trước cả người dùng của mình. Tải Apidog để xây dựng và quản lý các bộ kiểm thử mà CLI chạy.

Câu hỏi thường gặp

PHP2Shell có đang bị khai thác không? Amazon đã thấy các nỗ lực từ ngày 17 tháng 10 và nói rằng nó hiện đang bị khai thác rộng rãi; Cloudflare và watchTowr cũng báo cáo các cuộc tấn công. Tính đến ngày 22 tháng 10, CISA vẫn chưa xác nhận việc bị khai thác.

Framework của tôi có bảo vệ tôi không? Không. CVE-2026-109618 kích hoạt trong khi PHP phân tích phần thân yêu cầu, trước khi Laravel, Symfony hay WordPress được tải.

Tôi đang dùng shared hosting. Tôi phải làm gì? Hãy kiểm tra trang trạng thái của nhà cung cấp hosting. SiteGround và những đơn vị khác nói rằng họ đã vá. Nếu nhà cung cấp của bạn chưa nói gì, hãy hỏi họ.

Đặt session.upload_progress.enabled=0 có đủ không? Không. Nó chỉ bao phủ một con đường của một CVE. Hãy vá.

Tôi có cần thay đổi/xoay vòng các secret không? CVE-2026-109619 cho phép rò rỉ bộ nhớ. Nếu log cho thấy dấu hiệu bị xâm phạm từ ngày 17 tháng 10, hãy xoay vòng mật khẩu cơ sở dữ liệu, khóa API và các secret của session mà tiến trình PHP có thể đọc được.

Kết luận

Hãy nâng cấp lên 8.5.12, 8.4.27, 8.3.36 hoặc 8.2.35. Khởi động lại mọi worker. Tìm những instance PHP mà bạn đã quên. Kiểm tra log ngược về ngày 17 tháng 10. Sau đó chạy các bài kiểm thử API của bạn để bản sửa lỗi không trở thành sự cố gián đoạn tiếp theo. Nếu PHP của bạn đang ở 8.1 hoặc cũ hơn, đây chính là tuần để cuối cùng rời bỏ nó.

Thực hành thiết kế API trong Apidog

Khám phá cách dễ dàng hơn để xây dựng và sử dụng API