PHP2Shell: Dua Celah RCE Kritis pada PHP (CVE-2026-109618 dan CVE-2026-109619)

Panduan ini ditujukan untuk administrator VPS dan pemilik website. Contoh perintah di bawah bersifat pemeriksaan dan pemulihan pada server milik sendiri. Artikel tidak menyertakan payload eksploit untuk mengambil alih sistem. Pengujian keberhasilan patch dilakukan dengan memeriksa versi, konfigurasi, layanan, dan fungsi normal aplikasi di lingkungan yang terkendali.

Ilustrasi keamanan server untuk artikel PHP2Shell.
Ilustrasi keamanan server untuk artikel PHP2Shell.

1. Ringkasan: apa yang terjadi pada PHP?

Pada 21 Oktober 2026, tim PHP mengumumkan dua kerentanan kritis pada inti interpreter PHP yang dapat memungkinkan Remote Code Execution (RCE) tanpa autentikasi dalam kondisi tertentu. Keduanya dikenal sebagai PHP2Shell:

  • CVE-2026-109618 — RCE via Out-of-Memory (OOM) corruption. Saat PHP mengalami kehabisan memori ketika request sedang diproses, jalur pembersihan request dapat menemukan struktur internal yang belum valid.
  • CVE-2026-109619 — RCE via stale global state. Worker PHP yang digunakan ulang dapat menyimpan referensi ke state milik request sebelumnya setelah memori request tersebut dibebaskan.

Kedua masalah ini berada pada runtime PHP, bukan pada satu framework tertentu. PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, dan LiteSpeed yang melayani request web perlu diperiksa. PHP menyebut risiko tertinggi yang telah didemonstrasikan ada pada Apache mod_php; analisis sumber juga menyatakan FPM tetap perlu dianggap berisiko. Baca pengumuman PHP.

2. Bagaimana bug bekerja?

CVE-2026-109618 — OOM corruption

OOM adalah kondisi ketika proses tidak dapat memperoleh alokasi memori yang diminta. PHP menggunakan mekanisme penghentian alur saat OOM. Pada jalur tertentu, request dapat dihentikan ketika struktur internal baru terbentuk sebagian. Proses penutupan request kemudian berpotensi membaca struktur yang belum berada pada keadaan valid.

Advisory PHP menjelaskan sejumlah bentuk input multipart yang dapat meningkatkan penggunaan memori, seperti bagian multipart dengan header berlebihan, nama field bertingkat, atau request yang lolos pemeriksaan ukuran awal namun menghasilkan pemakaian memori besar ketika diurai. Ini menjelaskan mengapa batas ukuran request dan upload tetap penting, tetapi tidak menggantikan patch.

CVE-2026-109619 — stale global state

Worker PHP dapat menangani beberapa request secara bergantian. Sebuah operasi dalam request pertama dapat meninggalkan referensi state internal. Jika proses berakhir melalui fatal error sebelum state dibersihkan, kemudian worker tetap menyimpan referensi itu dan memproses request berikutnya, operasi awal pada request berikutnya dapat menyentuh state yang sudah tidak valid. Inilah bentuk use-after-free.

Skema sederhana CVE-2026-109619
  1. Request A menjalankan operasi yang menyimpan state internal.
  2. Terjadi fatal error sehingga pembersihan normal tidak tuntas.
  3. Memori Request A dibebaskan, tetapi referensinya tertinggal pada worker.
  4. Worker yang sama menerima Request B.
  5. Operasi awal Request B menyentuh referensi lama sebelum state diinisialisasi ulang.

Skema ini menjelaskan konsep bug, bukan resep atau payload untuk mengeksploitasinya.

3. Versi yang terdampak dan versi perbaikan

CabangRentan jika lebih rendah dariVersi perbaikan minimum
PHP 8.58.5.128.5.12
PHP 8.48.4.278.4.27
PHP 8.38.3.368.3.36
PHP 8.28.2.358.2.35

PHP 8.1 dan versi yang lebih lama sudah tidak menerima pembaruan reguler dari proyek PHP. Vendor Linux/LTS tertentu dapat memberikan backport patch. Untuk paket vendor, cocokkan changelog atau advisory vendor; jangan hanya membandingkan nomor versi upstream. PHP juga menyediakan backport sumber minimal untuk beberapa cabang lama bagi pengguna yang membangun sendiri, tetapi jalur yang paling baik adalah memakai cabang yang masih didukung.

Catatan siklus dukungan: PHP 8.2 dijadwalkan mencapai akhir dukungan pada 31 Desember 2026. Walaupun PHP 8.2.35 memperbaiki dua CVE ini, rencanakan migrasi ke cabang yang masih didukung agar tetap menerima pembaruan keamanan berikutnya.

Catatan terpisah: Brotli pada build PHP Windows

Pada 26 Oktober 2026, tim PHP juga menerbitkan build Windows yang diperbarui: 8.5.12-1, 8.4.27-1, 8.3.36-1, dan 8.2.35-1. Build tersebut menyertakan Brotli 1.2.1 untuk memperbaiki CVE-2026-111497 pada decoder Brotli yang dapat dijangkau melalui ekstensi cURL ketika dekompresi otomatis respons HTTP diaktifkan. Ini adalah isu library Brotli yang berbeda dari dua CVE PHP2Shell. Pengumuman ini terutama berlaku bagi paket Windows; jangan menganggap patch ini sebagai alasan untuk menunda update PHP Linux atau Node.js.

4. Pemeriksaan aman sebelum memperbaiki

Langkah berikut hanya membaca informasi server. Jalankan melalui SSH sebagai administrator:

  1. Lihat PHP CLI default.
php -v
command -v php
php --ini
  1. Inventarisasi PHP yang dipasang aaPanel. aaPanel biasanya menyimpan beberapa versi di /www/server/php/. Tidak semua server memiliki struktur yang sama, jadi pastikan direktori tersedia.
ls -lah /www/server/php/ 2>/dev/null

for d in /www/server/php/*; do
  [ -x "$d/bin/php" ] && "$d/bin/php" -v | head -n 1
  [ -x "$d/sbin/php-fpm" ] && "$d/sbin/php-fpm" -v | head -n 1
done
  1. Periksa worker PHP-FPM yang sedang berjalan.
ps -ef | grep '[p]hp-fpm'
ls -1 /etc/init.d/php-fpm-* 2>/dev/null

Jangan berhenti pada output php -v. Setiap website aaPanel dapat ditetapkan ke versi PHP-FPM yang berbeda. Periksa pilihan PHP pada pengaturan masing-masing website dan cocokkan dengan binary FPM-nya.

5. Tutorial update PHP di aaPanel — langkah demi langkah

  1. Catat semua website dan versi PHP. Buka aaPanel → Website, periksa kolom versi PHP untuk setiap domain. Catat juga cron job, queue worker, dan aplikasi CLI yang menggunakan PHP.
  2. Buat cadangan. Backup database, file website, file environment, konfigurasi PHP, serta konfigurasi pool FPM. Simpan backup di lokasi yang tidak ikut tertimpa saat update.
  3. Periksa kompatibilitas aplikasi. Pastikan versi Laravel, Composer, ekstensi PHP, dan paket aplikasi mendukung versi PHP tujuan. Lakukan pengujian pada staging bila tersedia.
  4. Perbarui setiap cabang PHP yang dipakai. Buka aaPanel → App Store/Software → PHP versi yang digunakan. Gunakan tombol update atau mekanisme upgrade yang disediakan panel/vendor. Pastikan hasil akhirnya memenuhi versi patch minimum pada tabel. Jangan hanya memasang versi PHP baru lalu membiarkan website tetap menggunakan versi lama.
  5. Restart PHP-FPM terkait. Gunakan tombol Restart pada halaman pengelolaan PHP di aaPanel untuk setiap versi yang diperbarui. Restart diperlukan agar worker lama berhenti dan binary yang sudah dipatch digunakan.
  6. Uji aplikasi. Periksa halaman utama, login, upload file, API, koneksi database, queue worker, scheduler/cron, dan proses yang bergantung pada ekstensi PHP.
  7. Verifikasi ulang. Jalankan binary PHP dan PHP-FPM dari cabang yang diperbarui. Cocokkan kembali versi dengan website di aaPanel.

Jika PHP dipasang dari luar aaPanel, update melalui repositori/vendor yang sama. Hindari mencampur file binary dari beberapa sumber karena ekstensi dan library bisa tidak cocok.

6. Mitigasi sementara jika update belum bisa dilakukan

Catatan penting: tidak ada mitigasi konfigurasi umum yang membuat PHP rentan sepenuhnya aman. Update ke rilis yang telah dipatch tetap satu-satunya solusi lengkap.

  • Untuk CVE-2026-109618: advisory PHP menyebut memory_limit=-1 sebagai mitigasi konfigurasi utama terhadap jalur OOM yang telah dikonfirmasi, tetapi ini bukan solusi lengkap. Menghapus batas memori per-request dapat meningkatkan risiko kehabisan RAM/DoS. Jangan menerapkannya secara global tanpa analisis kapasitas, isolasi worker, dan pemantauan; utamakan update.
  • Untuk CVE-2026-109619: pada PHP 8.5, fatal_error_backtraces=0 hanya menutup jalur producer tertentu yang telah dikonfirmasi; ini bukan perlindungan untuk semua state internal. Tidak ada mitigasi konfigurasi generik yang meliputi semua operasi.
  • Batasi request multipart: atur post_max_size, upload_max_filesize, max_file_uploads, max_input_vars, dan max_input_nesting_level sesuai kebutuhan. PHP memberi contoh post_max_size=8M untuk aplikasi tanpa upload dan 32M bila upload diperlukan; sesuaikan dengan kebutuhan nyata aplikasi. Terapkan batas ukuran body dan batas multipart di reverse proxy/web server juga. Ini mengurangi risiko OOM/DoS, tetapi bukan pengganti patch.

Imbauan tambahan PHP pada 23 Oktober 2026: session upload progress

PHP menyarankan untuk sementara menonaktifkan session upload progress sampai rilis bugfix berikutnya guna menutup jalur RCE yang tidak umum. Jalur ini memerlukan kombinasi khusus: aplikasi mengatur session.serialize_handler menjadi php_binary atau php_serialize, kemudian mengubahnya saat runtime menjadi php sebelum session_start(), sementara upload progress tetap aktif.

Jika belum memiliki alasan untuk memakai fitur tersebut, tambahkan pengaturan berikut pada php.ini versi yang digunakan atau konfigurasi FPM yang berlaku sebelum request parsing:

session.upload_progress.enabled = Off

Untuk pool FPM tertentu, pengaturan admin dapat digunakan jika sesuai konfigurasi pool:

php_admin_value[session.upload_progress.enabled] = 0

Setelah perubahan, restart semua worker PHP-FPM terkait, lalu verifikasi konfigurasi aktif. Jangan mengandalkan ini_set() pada aplikasi atau file .user.ini untuk mitigasi ini, karena pengaturan harus berlaku sebelum parser request bekerja. Ini hanya mitigasi untuk jalur spesifik CVE-2026-115560, bukan pengganti update PHP2Shell.

Pengaturan tambahan yang sangat terbatas

Untuk PHP 8.5 yang belum dapat diperbarui, PHP juga menyebut fatal_error_backtraces=0 sebagai cara memutus jalur backtrace fatal tertentu yang telah dikonfirmasi. Pengaturan ini tidak menutup jalur state internal lain. Pada FPM, beberapa administrator dapat mempertimbangkan pm.max_requests=1 untuk mendaur ulang worker setelah satu request apabila performa bukan prioritas; dampaknya adalah overhead proses yang lebih besar dan ini juga tidak menghapus bug. Terapkan perubahan tersebut hanya setelah menguji pool terkait.

; PHP 8.5 saja — mitigasi untuk jalur fatal-backtrace yang dikonfirmasi
fatal_error_backtraces = Off

; Opsional pada pool FPM jika risiko/performa telah dievaluasi
pm.max_requests = 1

Jangan mengandalkan penyembunyian pesan error melalui display_errors, error_reporting, atau operator @ sebagai mitigasi. PHP menyatakan pengaturan tersebut tidak memutus jalur bug.

7. Simulasi pemeriksaan aman di lingkungan lab

Tujuan latihan ini adalah memeriksa apakah kontrol upload dan logging aplikasi bekerja, bukan memicu OOM atau menjalankan exploit. Jangan melakukan stress test atau mengirim multipart malformed ke server produksi.

  1. Buat salinan staging dari aplikasi dan database dengan data uji, bukan data pelanggan.
  2. Pastikan staging menggunakan runtime PHP yang sudah dipatch. Catat versi CLI dan FPM yang digunakan.
  3. Gunakan form upload normal aplikasi dengan file kecil yang valid. Pastikan ukuran file yang diperbolehkan sesuai kebijakan aplikasi.
  4. Uji batas ukuran menggunakan file uji yang sedikit melewati batas upload yang telah ditetapkan. Hasil yang diharapkan adalah penolakan terkontrol, bukan worker crash.
  5. Periksa log aplikasi, PHP-FPM dan Nginx. Pastikan kegagalan upload tercatat dengan wajar dan tidak menimbulkan restart worker berulang.
  6. Ulangi setelah perubahan konfigurasi, lalu dokumentasikan versi, batas upload, hasil tes, dan waktu restart.

Latihan tersebut membantu memeriksa hardening, tetapi tidak dapat membuktikan apakah sebuah binary lama dapat dieksploitasi. Verifikasi patch tetap dilakukan dari versi/build yang diperbaiki dan catatan vendor.

8. Cara verifikasi setelah update

  1. Periksa kembali versi CLI dan FPM dari cabang yang telah diperbarui.
  2. Pastikan website di aaPanel benar-benar diarahkan ke versi PHP-FPM yang sudah dipatch.
  3. Pastikan proses lama telah diganti: periksa waktu mulai worker melalui daftar proses atau restart layanan dari panel.
  4. Uji fungsi normal aplikasi, termasuk upload dan endpoint API. Jangan mengirim payload exploit ke server produksi.
  5. Periksa log PHP-FPM dan web server untuk error baru, lonjakan penggunaan memori, proses tidak dikenal, atau request aneh.
Contoh pemeriksaan fungsional yang aman

Gunakan halaman health-check aplikasi yang sudah ada atau request biasa ke halaman publik. Keberhasilan membuka halaman hanya membuktikan aplikasi merespons, bukan membuktikan patch. Bukti utama patch adalah versi runtime/paket yang tepat dan worker sudah menggunakan binary baru.

9. Jika server diduga sudah dieksploitasi

Memperbarui PHP tidak otomatis menghapus backdoor yang mungkin sudah dipasang sebelumnya. Simpan log dan bukti, batasi akses jaringan jika insiden aktif, periksa akun baru, cron job, file PHP yang berubah, proses asing, koneksi keluar, dan perubahan konfigurasi. Rotasi password database, token API, SSH key, dan secret aplikasi dari perangkat bersih. Untuk insiden serius, bangun ulang server dari image tepercaya dan pulihkan hanya data yang sudah diperiksa.

10. Kesimpulan

PHP2Shell adalah dua kerentanan pada interpreter PHP yang memiliki jalur eksploitasi berbeda. Jangan mengandalkan WAF atau batas upload sebagai solusi utama. Inventarisasi seluruh runtime, perbarui setiap PHP-FPM/handler yang menerima request, restart worker, lalu verifikasi versi yang benar-benar dipakai setiap website.

Referensi resmi

Diperiksa 31 Oktober 2026. Versi paket distro bisa membawa backport. Cocokkan selalu dengan catatan vendor. Artikel ini merupakan panduan administrasi defensif, bukan instruksi eksploitasi.

Previous Post
No Comment
Add Comment
comment url