22 Tháng 10, 2026
Lỗ hổng PHP CVE-2026-109618 và CVE-2026-109619: bản vá, cách kiểm và cách cầm cự

Lỗ hổng PHP CVE-2026-109618 và CVE-2026-109619 là hai lỗi bộ nhớ cho phép kẻ tấn công chưa có tài khoản chạy mã từ xa bằng quyền của tiến trình web, chỉ bằng cách gửi request tới một đường dẫn PHP bất kỳ. Nhóm bảo mật PHP công bố cả hai ngày 21/10/2026 với mức Critical, bản vá nằm trong PHP 8.5.12, 8.4.27, 8.3.36 và 8.2.35. Sáng 22/10/2026 tụi em đọc trực tiếp hai advisory gốc trên GitHub, changelog 8.3.36 trên php.net và trang trạng thái gói của CloudLinux, rồi viết lại thành bài này cho người đang quản server: lỗi nằm ở đâu, bản nào đã vá, kiểm bằng lệnh gì, và nếu chưa cập nhật được ngay thì cầm cự bằng cách nào.
Tóm tắt nhanh
- Hai lỗi cùng nằm trong lõi PHP, cùng mức Critical. CloudLinux ghi điểm CVSS v4.0 là 9.2 cho cả cặp. Không cần đăng nhập, không cần biết site chạy gì.
- CVE-2026-109618 xảy ra khi PHP hết bộ nhớ giữa lúc đang đọc dữ liệu upload. CVE-2026-109619 xảy ra khi request sau dùng lại trạng thái cũ mà request trước để sót lại trong cùng một worker.
- Apache mod_php là cấu hình dễ dính nhất. PHP-FPM, FrankenPHP và LiteSpeed LSAPI cũng nằm trong diện bị ảnh hưởng, mức chứng minh khai thác khác nhau.
- Bản vá: 8.5.12, 8.4.27, 8.3.36, 8.2.35. Nhánh 7.4, 8.0 và 8.1 không có bản phát hành chính thức, nhóm bảo mật PHP chỉ công bố mã nguồn backport tối thiểu.
- Advisory nói thẳng cập nhật là cách duy nhất xử lý trọn vẹn. Tắt
session.upload_progress.enabledchỉ chặn một đường đã xác nhận.
Hai lỗ hổng này là gì, và vì sao nặng hơn một bản vá PHP thông thường
Cả hai lỗi cùng một họ: PHP cố thoát khỏi một request đang hỏng giữa chừng nhưng để lại bộ nhớ ở trạng thái không hợp lệ, rồi một đoạn mã khác sau đó đọc đúng vùng nhớ ấy như thể nó còn nguyên vẹn. Từ chỗ đọc nhầm đó, kẻ tấn công sắp xếp lại heap để biến lỗi đọc thành thực thi mã. Hậu quả được ghi trong advisory là chạy mã từ xa bằng quyền của tài khoản web, tức là toàn bộ thư mục mã nguồn, file cấu hình chứa mật khẩu database và mọi thứ tài khoản đó ghi được.
| Hạng mục | CVE-2026-109618 | CVE-2026-109619 |
|---|---|---|
| Mã advisory | GHSA-w8hw-w9fx-j79w | GHSA-6wmf-4rv5-p3rp |
| Tên gọi | RCE via OOM corruption | RCE via stale global state |
| Gốc lỗi | Hết bộ nhớ khi bộ nhớ request chưa khởi tạo xong | Trạng thái request cũ còn sót, request sau dùng lại |
| Ngày công bố | 21/10/2026 | 21/10/2026 |
| Điều kiện | Gửi được request multipart | Hai request rơi vào cùng một worker |
| Cần tài khoản | Không | Không |
Điểm làm hai lỗi này đáng sợ hơn một bản vá PHP hằng tháng là chúng nằm ở bước PHP chuẩn bị request, trước khi bất kỳ dòng code nào của website chạy. Anh chị có thể viết ứng dụng sạch tới đâu thì phần mềm của anh chị vẫn không đứng được ở giữa. Bản vá mới là thứ chặn được. Bản 8.3.35 phát hành ngày 24/09/2026 đã vá chín lỗi khác (FPM, OpenSSL, SOAP, Phar, MySQLnd), nên server nào chưa theo kịp 8.3.35 thì cần nhảy thẳng lên 8.3.36 chứ không dừng giữa chừng.
CVE-2026-109618: PHP hết bộ nhớ đúng lúc đang đọc dữ liệu upload
PHP thoát khỏi lỗi hết bộ nhớ bằng lệnh longjmp(), nhảy thẳng ra khỏi ngữ cảnh đang chạy mà không đi qua các bước dọn dẹp. Ở một số chỗ, bộ nhớ của request đã truy cập được nhưng chưa khởi tạo xong, và nếu bất kỳ lần cấp phát nào thất bại đúng lúc đó thì PHP để request ở trạng thái hỏng và bước kết thúc request sau đó đọc hoặc rẽ nhánh theo dữ liệu hỏng này. Lần cấp phát thất bại không cần liên quan gì tới vùng nhớ hỏng.
Kẻ tấn công không phải đoán mò để làm PHP hết bộ nhớ, vì advisory liệt kê ba cách ép chắc chắn qua dữ liệu multipart, tức là kiểu request mà form upload file vẫn gửi:
- Request multipart không khai độ dài nội dung hợp lệ vẫn qua được bước kiểm tra
post_max_sizeban đầu, rồi tiếp tục đẩy dữ liệu vào. - Một phần multipart có thể mang số header không giới hạn. Header đó chiếm trong PHP nhiều bộ nhớ hơn hẳn kích thước trên đường truyền, nên một request nằm trong
post_max_sizevẫn làm cạnmemory_limit. - Các ô file rỗng không tính vào
max_file_uploadsnhưng vẫn tạo mảng thông tin file như thường, và tên trường lồng nhau nhân khối lượng dựng mảng lên.
Với Apache mod_php, bước kết thúc request chạy vô điều kiện kể cả khi bước khởi động request đã thất bại, và toàn bộ chuyện này xảy ra trước khi code ứng dụng bắt đầu. Advisory ghi đã khai thác thành công chạy mã từ xa qua HTTP trên mod_php với giới hạn input và bộ nhớ mặc định, trên cấu hình prefork nhiều worker bình thường. Thêm worker hay thêm lưu lượng khác chỉ làm tăng số lần thử, không làm điều kiện biến mất. PHP-FPM thì khác một chút. Khi bước khởi động request thất bại, FPM cho tiến trình con thoát và trạng thái hỏng không được dùng tiếp. Nguồn phân tích vẫn xếp FPM vào diện có thể bị ảnh hưởng vì OOM vẫn xảy ra được sau khi khởi động, nhưng advisory ghi rõ chưa có bản khai thác trọn vẹn nào cho FPM với lỗi này.
CVE-2026-109619: request sau dùng lại trạng thái mà request trước để sót
PHP giữ nhiều biến toàn cục trỏ vào bộ nhớ thuộc về từng request, gồm trạng thái lỗi, session, object và extension. Nếu request kết thúc bất thường trước khi trạng thái ấy được xoá, vùng heap của request bị giải phóng trong khi worker vẫn giữ con trỏ trỏ vào đó. Một thao tác nào đó ở request kế tiếp, chạy trước bước khởi tạo bình thường, sẽ đọc con trỏ này: đó là use-after-free, và với heap được bố trí khéo thì thành chạy mã từ xa.
Khai thác cần đủ hai vai. Vai thứ nhất là thao tác sinh ra, ghi trạng thái của request vào chỗ toàn cục. Vai thứ hai là thao tác tiêu thụ ở request sau, đọc hoặc giải phóng trạng thái ấy trước khi PHP kịp khởi tạo lại. Hai request phải rơi vào cùng một worker, và nhiều worker hay tái chế worker chỉ làm giảm xác suất mỗi lần thử.
Advisory xác nhận hai đường tiêu thụ. Đường đầu là cảnh báo lúc áp cấu hình INI: một deprecation hay warning phát sinh trước khi request khởi tạo xong sẽ chạm vào trạng thái lỗi cũ, kể cả khi anh chị đã tắt display_errors, tắt log_errors, đổi error_reporting hoặc dùng @, vì trạng thái bị chạm trước khi PHP quyết định có hiển thị hay ghi log hay không. Đường thứ hai là tiến trình upload của session (session upload progress), đã bật mặc định và không cần ứng dụng gọi session_start(). Đường này được xác nhận khai thác ra chạy mã từ xa trên cả mod_php lẫn FPM. Với PHP 8.5 còn thêm một đường mạnh nhất: khi bật fatal_error_backtraces, lúc báo lỗi fatal PHP lưu trạng thái backtrace thuộc request và bước kết thúc luôn quên xoá nó. Đây là cơ sở của bản khai thác mod_php đã xác nhận. Điều khiến lỗi này khó đóng bằng cấu hình là advisory tự ghi rằng không có cách giảm thiểu cấu hình nào bao trọn mọi đường, vì một ứng dụng, extension hay đường server nào đó có thể để sót trạng thái hoặc đọc nó mà không để lại dòng log dự đoán được.
Ai bị ảnh hưởng: mod_php, FPM, FrankenPHP hay LiteSpeed
Theo PHP, mọi cài đặt PHP nhận request web đều thuộc diện bị ảnh hưởng. Mức độ khác nhau theo cách PHP được gọi:
| Cách chạy PHP | Với CVE-2026-109618 | Với CVE-2026-109619 |
|---|---|---|
| Apache mod_php | Khai thác chạy mã đã xác nhận, ngay ở bước khởi động request | Đã xác nhận qua backtrace fatal (PHP 8.5) và session upload progress |
| PHP-FPM | Xếp vào diện bị ảnh hưởng, chưa có bản khai thác trọn vẹn | Session upload progress đã xác nhận trên pool dynamic bình thường |
| FrankenPHP | Phân tích mã nguồn cho thấy nhiều khả năng bị ảnh hưởng như mod_php | Chưa xác lập đường INI sớm ở cấu hình mặc định, không có nghĩa là miễn nhiễm |
| LiteSpeed LSAPI | Giống FPM, khai thác theo ứng dụng, chưa kiểm chứng | Có thể áp INI sớm qua biến môi trường, thuộc diện có điều kiện |
Hai chi tiết cần đọc kỹ nếu anh chị chạy nginx cộng PHP-FPM, là kiểu server phổ biến nhất ở Việt Nam. Thứ nhất, FPM bị chạm bởi CVE-2026-109619 khi frontend gửi tham số PHP_VALUE hoặc PHP_ADMIN_VALUE tạo ra cảnh báo trước khởi tạo request, còn giá trị đặt trong pool FPM được áp từ lúc worker khởi động và .user.ini được áp sau khởi tạo nên không cấp đường tiêu thụ sớm này. Thứ hai, lỗi session upload progress vẫn đi được trên FPM nếu ứng dụng có một thao tác để lại trạng thái rồi gặp lỗi fatal.
Trên server dùng NGINX hay Apache kèm PHP, cách nhanh nhất để biết mình thuộc dòng nào là liệt kê các tiến trình đang chạy:
ps aux | grep -E "php-fpm: master|apache2|httpd|litespeed|frankenphp" | grep -v grep
Một máy có thể có nhiều master PHP-FPM cùng lúc, mỗi master ứng với một nhánh PHP cài song song. Khởi động lại một master chỉ đụng tới nhánh của nó.
Bản đã vá theo từng nhánh PHP
Changelog PHP 8.3.36 trên php.net chỉ có một mục duy nhất trong phần Core, ghi nhận cả hai mã GHSA là “Avoid state corruption via bailout”. Cả hai lỗi cùng được sửa bằng một thay đổi trong lõi, nên anh chị không phải cân nhắc từng lỗi riêng. Ngày hiển thị trong changelog là 22/10/2026, còn CloudLinux ghi bản upstream xuất hiện từ 14:00 UTC ngày 21/10/2026, nên nếu thấy hai nguồn lệch một ngày thì đó là lệch cách ghi, không phải hai bản khác nhau.
| Nhánh PHP | Bản đã vá | Ghi chú |
|---|---|---|
| 8.5 | 8.5.12 | Có thêm đường fatal_error_backtraces |
| 8.4 | 8.4.27 | |
| 8.3 | 8.3.36 | Gom luôn cả bản vá 8.3.35 ngày 24/09/2026 |
| 8.2 | 8.2.35 | Hết hỗ trợ ngày 31/12/2026 |
| 8.1, 8.0, 7.4 | Không có bản phát hành chính thức | Có mã nguồn backport tối thiểu do nhóm bảo mật PHP công bố |
Nhánh 7.4, 8.0 và 8.1 là chỗ nhiều server Việt Nam đang nằm, vì các control panel và theme cũ kéo nhiều site ở lại đó. Với ba nhánh này anh chị chỉ có hai đường thật: nhận gói backport từ nhà cung cấp hệ điều hành hay control panel (CloudLinux, TuxCare, distro của anh chị), hoặc chuyển site sang nhánh còn được vá. Tự biên dịch lại từ mã backport được nhưng tốn công hơn nhiều so với chuyển nhánh.
Gói CloudLinux và cPanel đã ra chưa, và vì sao số phiên bản vẫn “cũ”
Gói của CloudLinux dùng backport, nên số phiên bản vẫn thấp hơn số của PHP upstream: ea-php84 hiện là 8.4.26-2 chứ không phải 8.4.27, ea-php83 là 8.3.35-2, ea-php85 là 8.5.11-2. Đừng so số phiên bản để kết luận đã vá hay chưa. Cách đúng là tìm mã CVE trong changelog của gói:
rpm -q ea-php84-php-cli --changelog | grep -E 'CVE-2026-(109618|109619)'
rpm -q --changelog alt-php74-common | grep -E "CVE-2026-(109618|109619)"
Theo trang trạng thái CloudLinux cập nhật lúc 01:19 UTC ngày 22/10/2026, bản vá ea-php (cPanel EasyApache 4) đã vào kho stable từ 20:55 UTC ngày 21/10 cho ea-php52 tới ea-php85, bản alt-php đã vào stable cho CloudLinux 7, 8, 9 và hoàn tất lúc 00:07 UTC ngày 22/10, còn PHP gốc của CloudLinux mới ra bản stable cho 8.2 và 8.3 trên CloudLinux 9 và 8.2 trên CloudLinux 8. Các bản còn lại đang ở testing hoặc rollout sớm.
Metadata bảo mật OVAL và UpdateInfo chưa được công bố, nên yum --security và dnf updateinfo chưa liệt kê các gói này. Anh chị cập nhật bằng lệnh thường:
# CloudLinux 7
yum clean all && yum update "ea-php*"
# CloudLinux 8, 9, 10
dnf clean all && dnf upgrade "ea-php*"
/scripts/restartsrv_httpd
/scripts/restartsrv_apache_php_fpm
Với alt-php dùng yum update 'alt-php*' (CloudLinux 7) hoặc dnf upgrade 'alt-php*' (CloudLinux 8, 9, 10), xong khởi động lại Apache, PHP-FPM hoặc LiteSpeed. Máy Debian hay Ubuntu thì kiểm bằng apt changelog php8.3-fpm | grep -E "CVE-2026-(109618|109619)" sau khi apt update, và đây là việc anh chị tự làm được trong vài phút.
Chưa cập nhật ngay được thì cầm cự thế nào
Advisory mở đầu phần giảm thiểu bằng cảnh báo rằng cập nhật là cách duy nhất xử lý trọn vẹn, và tụi em đọc câu này theo nghĩa đen: mọi thứ bên dưới chỉ mua thời gian. Với CVE-2026-109618, cấu hình giảm thiểu chính theo advisory là đặt và ép memory_limit=-1 ở cấp quản trị, vì bỏ giới hạn bộ nhớ dự đoán được của từng request thì kẻ tấn công mất cách ép OOM có kiểm soát. Nghe ngược đời nhưng đúng vậy, và nó chưa đủ: nếu mmap() hoặc một lần cấp phát nền khác thất bại, PHP vẫn đi vào longjmp().
Tụi em không khuyên đặt memory_limit=-1 trên server dùng chung khi chưa có giới hạn thay thế, vì một script lỗi vòng lặp sẽ ăn hết RAM của cả máy. Advisory gợi ý cgroup memory.max làm lớp thay thế, kèm lưu ý rằng giết cả cgroup có thể giết luôn master lẫn mọi worker, nên mỗi worker cần nhóm riêng. Tuyệt đối không dùng RLIMIT_AS hay RLIMIT_DATA, vì hai giới hạn này làm mmap() thất bại đúng vào đường longjmp() đang bị lỗi.
Danh sách việc cầm cự, xếp theo thứ tự làm:
- Đặt
session.upload_progress.enabled=0trong cấu hình quản trị rồi khởi động lại toàn bộ worker. Chặn đường session đã xác nhận, không chặn các đường khác. Advisory còn khuyên giữ tắt kể cả sau khi vá, vì tính năng này ít người dùng và ít được kiểm thử. - PHP 8.5: đặt
fatal_error_backtraces=0rồi khởi động lại worker. Bỏ nguồn sinh trạng thái của bản khai thác đã xác nhận. - Giữ
post_max_sizevừa phải và giới hạn độc lập kích thước đã giải mã ở frontend. Giảmmax_input_nesting_level, giới hạn số biến input, số phần multipart, số header mỗi phần và số file upload. - Ứng dụng không dùng multipart thì chặn loại request này ở frontend trước khi nó tới PHP.
- Dọn mọi cảnh báo, deprecation lúc áp INI: bỏ các directive lỗi thời, và ưu tiên đặt giá trị trong
php.ini, pool FPM hoặc cấu hình server thay vì truyềnPHP_VALUEtheo từng request. - Nếu hiệu năng không phải vấn đề, đặt
pm.max_requests=1để mỗi worker chỉ phục vụ một request, cắt đứt điều kiện hai request cùng một worker.
Tường lửa ứng dụng giúp được một phần. Imunify360 đã ra ba bộ luật trong ngày 21/10/2026: 8.83 lúc 09:08 UTC chặn mẫu request khai thác đã biết, 8.84 lúc 13:07 UTC chặn công cụ khai thác công khai, 8.85 lúc 17:17 UTC chặn các biến thể công cụ và upload dị dạng. Trang CloudLinux cũng ghi chưa có luật nào chặn đường OOM của CVE-2026-109618. Coi WAF là lớp phụ chứ không phải bản vá.
Đã bị khai thác chưa, và cách nhận ra dấu hiệu
Theo blog CloudLinux, một công cụ khai thác công khai đang được dùng để quét hàng loạt, trong khi Huntress và watchTowr chưa ghi nhận khai thác thật tính tới sáng 21/10/2026. Hai thông tin này không mâu thuẫn: quét hàng loạt là bước dò tìm, còn khai thác thành công trên server thật lại cần thử nhiều lần vì phải khớp hai request vào một worker.
Điều đó cũng cho anh chị manh mối để soát log. Advisory không hứa log sẽ lộ dấu vết, và nói rõ không có dòng lỗi nào cũng chưa chắc là an toàn. Việc khả thi là bật tạm log_errors=On, error_log chạy được và error_reporting=E_ALL trong cấu hình khởi động ở một đợt kiểm riêng, rồi tìm trong log Apache, PHP-FPM và proxy các nhóm sau:
- Warning và deprecation lặp đi lặp lại trước khi script đích chạy.
- Chẩn đoán phát sinh lúc extension hay server dọn dẹp, sau khi trạng thái lỗi bình thường đã được xoá.
- Lỗi fatal, parse error, uncaught error và dòng
Maximum execution time exceeded. - Một loạt request multipart bất thường tới cùng một địa chỉ, nhất là request không có độ dài nội dung hợp lệ.
Nếu đã thấy dấu hiệu lạ, đừng chỉ vá rồi bỏ đó: cập nhật xong còn phải quét mã độc, đổi mật khẩu database và khoá bí mật trong file cấu hình. Hướng đi từng bước nằm ở bài phát hiện và xử lý website dính mã độc và danh sách 14 dấu hiệu website bị hack.
Checklist 10 bước trong ngày 22/10/2026
- Liệt kê mọi nhánh PHP đang chạy trên máy, gồm cả nhánh cài song song cho một vài site. Một master PHP-FPM, một nhánh.
- Ghi lại SAPI từng nhánh: mod_php, FPM, LSAPI hay FrankenPHP. Mod_php xử lý trước.
- Với mỗi nhánh, xác định thuộc nhóm có bản vá chính thức (8.2 tới 8.5) hay nhóm chỉ có backport (7.4, 8.0, 8.1).
- Cập nhật bằng trình quản lý gói của hệ điều hành hoặc control panel. Máy biên dịch từ mã nguồn thì lấy 8.x.y đã vá từ trang tải của PHP.
- Khởi động lại đúng từng master: Apache, từng PHP-FPM, LiteSpeed. Cập nhật gói mà chưa khởi động lại thì worker cũ vẫn chạy mã cũ.
- Xác nhận bằng changelog gói (
rpm -q … --changeloghoặcapt changelog), không dựa vào số phiên bản của gói backport. - Đặt
session.upload_progress.enabled=0nếu code không dùng. Kiểm bằnggrep -rn "upload_progress" wp-contentvới site WordPress, hoặc grep thư mục mã nguồn của ứng dụng. - Rà
post_max_size,max_file_uploads,max_input_nesting_levelvà giới hạn kích thước request ở nginx, Apache hoặc proxy phía trước. - Soát log lỗi PHP và log web server tìm các nhóm dấu hiệu ở mục trước.
- Ghi lại ngày giờ cập nhật và bản đang chạy của từng máy, để đợt vá sau không phải đi dò lại từ đầu.
Cả mười bước này anh chị tự làm được, không cần thuê ai, nếu có quyền root và một cửa sổ bảo trì vài chục phút.
Tụi em xử lý hạ tầng của mình theo thứ tự nào
Sáng 22/10/2026, việc đầu tiên tụi em làm không phải cập nhật mà là đếm. Trên hạ tầng tụi em quản có ba nhánh PHP chạy song song, mỗi nhánh một master PHP-FPM riêng, trong đó có nhánh cũ nằm ngoài diện có bản phát hành chính thức. Đếm ra rồi mới biết nhánh nào chỉ cần cập nhật gói, nhánh nào phải chuyển. Kinh nghiệm tụi em rút ra là sau khi cập nhật gói, phải đi khởi động lại từng master một, vì lệnh restart của một dịch vụ không chạm tới hai master còn lại.
Chuyển nhánh PHP cho một website là việc có rủi ro thật: theme và plugin viết cho PHP 7.4 có thể phát sinh lỗi trên 8.x, nên tụi em thử trên bản sao trước rồi mới đổi pool. Nếu anh chị có nhiều website cũ chạy trên nhánh không còn bản vá, hoặc không có thời gian ngồi kiểm từng máy, tụi em nhận kiểm tra và xử lý theo dịch vụ chăm sóc website, hoặc chuyển sang cloud VPS do tụi em quản trị. Còn không, mười bước ở trên đủ để anh chị tự lo xong trong buổi chiều.
Gọi hotline 1900 636 648 và nói rõ máy anh chị đang chạy nhánh PHP nào, đang dùng control panel nào. Tụi em trả lời được ngay nhánh đó có bản vá chưa.
Đọc tiếp để dọn nốt phần còn lại của server
Vá PHP chỉ đóng một cánh cửa. Phần còn lại của việc giữ server nằm ở những bài này: server là gì và VPS là gì cho người mới quản máy, SSH là gì để ra lệnh an toàn, LiteSpeed Web Server nếu anh chị dùng LSAPI, tường lửa là gì và DDoS là gì cho lớp chặn phía trước, sao lưu dữ liệu website trước mỗi lần nâng cấp, bảo mật website và plugin bảo mật WordPress, công cụ quét mã độc, cách chọn mua hosting và danh sách nhà cung cấp hosting Việt Nam.
Nguồn tụi em đã đọc
- GHSA-w8hw-w9fx-j79w, RCE via OOM corruption, nhóm bảo mật PHP, công bố 21/10/2026.
- GHSA-6wmf-4rv5-p3rp, RCE via stale global state, nhóm bảo mật PHP, công bố 21/10/2026.
- Changelog PHP 8, mục phiên bản 8.3.36.
- Bài của CloudLinux về hai CVE và trang trạng thái gói đã vá, cập nhật lần cuối 01:19 UTC ngày 22/10/2026.
Số liệu trong bài đối chiếu tới 22/10/2026. Trạng thái gói của CloudLinux còn đổi theo giờ, anh chị mở trang trạng thái để xem bản mới nhất trước khi cập nhật.
Bài viết liên quan
Dịch vụ thiết kế
website chuyên nghiệp
Sở hữu website với giao diện đẹp, độc quyền 100%, bảo hành trọn đời với khả năng
mở rộng tính năng linh hoạt theo sự phát triển doanh nghiệp ngay hôm nay!































Khoá học AI miễn phí
Công cụ AI trong công việc
VI
EN


