Menutup PHP2Shell dalam 12 Hari: Catatan Penanganan Kerentanan PHP di Polmed
Nov 1, 2026 · UPA TIK Politeknik Negeri Medan
Pada 21 Oktober 2026, tim PHP merilis perbaikan untuk dua kerentanan yang dengan cepat dijuluki PHP2Shell. Keduanya memungkinkan penyerang menjalankan kode di server dari jarak jauh, tanpa perlu login. Karena celahnya ada di PHP itu sendiri, bukan di aplikasi tertentu, hampir setiap situs berbasis PHP ikut berisiko: sistem akademik, e-learning, portal informasi, sampai situs unit.
Bagi Politeknik Negeri Medan, yang menjalankan puluhan layanan berbasis PHP dengan usia dan teknologi yang beragam, ini bukan sekadar urusan menjalankan satu perintah pembaruan. Tulisan ini menceritakan bagaimana UPA TIK menanganinya: cara kami memetakan cakupan, memilih strategi untuk tiap jenis sistem, membangun perangkat sendiri agar prosesnya bisa diulang dan diaudit, dan apa yang kami pelajari.
Hasil singkatnya: dalam 12 hari, seluruh 48 aplikasi yang terdampak telah ditangani. 40 aplikasi kini berjalan di versi PHP yang sudah diperbaiki, dan 8 aplikasi yang sudah tidak diperlukan dinonaktifkan.
Kerentanannya
PHP2Shell terdiri dari dua CVE dengan skor CVSS v4.0 9.2:
- CVE-2026-109618: kerusakan memori yang dapat dipicu dari luar, berujung pada eksekusi kode dan kebocoran isi memori server.
- CVE-2026-109619: sisa status sesi (stale global state) yang dapat dimanfaatkan untuk menjalankan kode.
Perbaikannya tersedia di PHP 8.5.12, 8.4.27, 8.3.36 dan 8.2.35. Masalahnya, versi PHP 8.1 ke bawah sudah tidak didukung dan tidak menerima perbaikan resmi. Padahal banyak aplikasi lama, di institusi mana pun, masih berjalan di versi-versi tersebut.
Dua hari kemudian muncul kerentanan ketiga, CVE-2026-115560, pada fitur session upload progress. Kerentanan ini hanya bisa dieksploitasi bila tiga kondisi terpenuhi sekaligus, dan sampai tulisan ini dibuat belum ada perbaikan resmi. Tim PHP merekomendasikan mitigasi sementara: mematikan fitur tersebut lewat session.upload_progress.enabled = 0.
Langkah pertama: tahu apa yang kita punya
Kerentanan di tingkat bahasa pemrograman punya satu sifat yang merepotkan: ia ada di mana-mana sekaligus. Sebelum memperbaiki apa pun, kami perlu jawaban pasti untuk satu pertanyaan sederhana: PHP versi berapa yang benar-benar berjalan di balik setiap situs kita?
Jawabannya tidak selalu ada di dokumentasi. Satu server bisa menjalankan beberapa versi PHP untuk situs yang berbeda; aplikasi berbasis kontainer membawa PHP-nya sendiri di dalam image; dan versi yang tertulis di konfigurasi belum tentu sama dengan yang benar-benar dimuat.
Karena itu kami memulai dengan audit hanya-baca di semua server: tidak ada yang diubah, hanya dicatat. Dalam dua hari, kami punya inventaris lengkap berisi 48 situs dan aplikasi, versi PHP masing-masing, dan pengaturan sesinya. Gambarannya jelas sekaligus mengkhawatirkan: tidak ada satu pun yang berjalan di versi yang sudah diperbaiki, dan sebagian berjalan di versi PHP yang sudah lama tidak didukung.
Setiap aplikasi lalu diberi tingkat risiko:
| Tingkat | Jumlah | Kriteria |
| Critical | 21 | PHP versi lama yang tidak menerima perbaikan resmi |
| High | 20 | Versi didukung, terbuka ke internet, menangani data penting |
| Medium | 7 | Versi didukung, dampak lebih terbatas |
Inventaris ini menjadi sumber kebenaran tunggal untuk seluruh pekerjaan: setiap perubahan status, versi terverifikasi, dan tanggal penanganan dicatat di sana.
Satu masalah, tiga jalur penanganan
Tidak ada satu solusi yang cocok untuk semua. Setiap sistem kami tempatkan di salah satu dari tiga jalur, tergantung seberapa jauh PHP-nya bisa diperbarui di tempat.
Jalur 1: Patch di tempat
Untuk server dengan sistem operasi yang masih didukung, jalurnya paling lurus: perbarui paket PHP ke rilis yang aman, matikan upload progress, verifikasi. Untuk versi PHP lama yang tidak lagi didukung secara resmi, kami memakai paket dari repositori komunitas yang menyediakan backport perbaikan PHP2Shell.
Satu prinsip yang kami pegang: jangan percaya nomor versi saja. Setiap paket diverifikasi dengan memastikan catatan perubahannya benar-benar mencantumkan kedua CVE. Prinsip ini terbukti berguna: build awal untuk beberapa versi lama ternyata belum memuat perbaikan lengkap, dan kami baru memasang build yang sudah dikoreksi.
Jalur 2: Upgrade dan migrasi
Sebagian aplikasi berjalan di PHP dan sistem operasi yang sudah terlalu tua untuk di-patch. Menambal di tempat bukan pilihan; satu-satunya jalan aman adalah maju.
Untuk aplikasi-aplikasi ini, kodenya diperbarui agar berjalan di PHP 8.4, lengkap dengan pembaruan framework, pemindaian kompatibilitas, dan pengujian. Setelah itu aplikasi dipindahkan ke server baru yang dibangun dari nol dengan prinsip yang lebih ketat: setiap aplikasi berjalan terisolasi dengan akunnya sendiri, lalu lintas publik hanya masuk melalui CDN dengan TLS end-to-end, akses administrasi dibatasi, dan pembaruan keamanan berjalan otomatis.
Aplikasi berbasis kontainer ditangani lewat jalur yang sama, versi PHP-nya dikunci ke rilis yang aman di dalam image, bukan lagi mengikuti tag yang bisa berubah sewaktu-waktu. Setiap perubahan melewati repositori Git sebagai commit, pull request, dan rilis bertag, sehingga jejaknya bisa ditelusuri.
Jalur 3: Pensiunkan
Inventaris juga mengungkap hal yang sering terlupakan: beberapa aplikasi sudah tidak digunakan, tetapi masih menyala dan terbuka ke internet. Untuk aplikasi seperti ini, keputusan paling aman adalah yang paling sederhana: matikan. Delapan aplikasi dinonaktifkan, dan dengan begitu permukaan serangan berkurang tanpa perlu memperbaiki apa pun.
Membangun perangkat sendiri
Menangani puluhan aplikasi satu per satu dengan perintah manual punya dua risiko: langkah yang terlewat, dan hasil yang sulit dibuktikan. Karena itu UPA TIK membangun empat perangkat internal selama penanganan. Tujuannya bukan otomatisasi semata, melainkan konsistensi dan bukti: setiap server ditangani dengan langkah yang sama, dan setiap langkah meninggalkan catatan.
Prinsip desainnya sama untuk keempatnya:
- Hanya-baca secara default. Audit dan pemindaian tidak pernah mengubah sistem.
- Rencana dulu, eksekusi kemudian. Perangkat yang mengubah sistem selalu menampilkan rencananya terlebih dahulu dan baru berjalan setelah dikonfirmasi.
- Selalu bisa mundur. Konfigurasi dicadangkan dan langkah rollback disiapkan sebelum perubahan apa pun.
- Setiap langkah menghasilkan bukti. Hasil disimpan dalam format yang bisa diperiksa auditor.
| Perangkat | Fungsi | Dibangun | Pengembangan lanjutan |
| Alat Audit PHP | Mencatat versi PHP dan pengaturan sesi tiap situs, tanpa mengubah apa pun | 21 Okt 2026 | 22 Okt: dukungan lingkungan kontainer |
| Alat Patch PHP | Memperbarui PHP, memverifikasi perbaikan di catatan paket, mencadangkan konfigurasi, menyiapkan rollback | 22 Okt 2026 | 23 Okt: mitigasi CVE-2026-115560 diterapkan otomatis |
| Pemindai CVE-2026-115560 | Memeriksa ketiga kondisi eksploitasi pada konfigurasi dan kode aplikasi | 23 Okt 2026 | Dipakai sebelum dan sesudah setiap perubahan |
| Alat Migrasi Aplikasi Lama | Menyiapkan server baru dan memindahkan aplikasi beserta basis datanya, lalu memverifikasi hasilnya | 27 Okt 2026 | 28 Okt – 1 Nov: dukungan basis data tambahan, verifikasi integritas data, sertifikat TLS, pembaruan dari Git, retensi cadangan |
Satu contoh mengapa verifikasi bawaan penting: saat memindahkan basis data berukuran puluhan gigabyte, alat migrasi tidak hanya memastikan proses restore selesai tanpa error, tetapi juga mencocokkan jumlah baris setiap tabel dengan sumbernya. Pemeriksaan inilah yang menangkap restore yang tampak berhasil padahal datanya belum lengkap, sebelum aplikasi dipakai pengguna.
Kronologi
| Tanggal | Kegiatan |
| 21 Okt | Perbaikan PHP2Shell dirilis. Alat Audit dibangun; audit dimulai |
| 22 Okt | Audit selesai; inventaris 48 aplikasi dan penilaian risiko tersusun. Alat Patch dibangun |
| 23 Okt | CVE-2026-115560 diumumkan. Alat Patch diperbarui; Pemindai CVE-2026-115560 dibangun |
| 24 Okt | Patch dan mitigasi di server yang dapat diperbarui di tempat |
| 25–26 Okt | Platform e-learning ditingkatkan ke versi baru di PHP 8.4 |
| 27 Okt | Keputusan migrasi untuk sistem lama. Alat Migrasi dibangun; server baru disiapkan |
| 28–29 Okt | Aplikasi lama dimigrasi ke server baru; aplikasi tak terpakai dinonaktifkan |
| 29 Okt – 1 Nov | Aplikasi kontainer dikunci ke PHP 8.4.27 dan dirilis ulang |
| 1 Nov | Penonaktifan terakhir; seluruh 48 aplikasi berstatus selesai |
Menghadapi kerentanan yang belum punya patch
CVE-2026-115560 menghadirkan tantangan berbeda: tidak ada versi PHP yang bisa dipasang untuk memperbaikinya. Yang bisa dilakukan adalah memastikan syarat eksploitasinya tidak terpenuhi.
Kerentanan ini membutuhkan tiga kondisi sekaligus:
- Handler serialisasi sesi diatur ke mode tertentu.
- Kode aplikasi mengubah handler tersebut saat berjalan.
- Fitur upload progress aktif, dan fitur ini aktif secara bawaan di PHP.
Kami menyerangnya dari dua sisi. Pertama, kondisi 3 dimatikan di semua lingkungan, termasuk yang sudah di-patch, sehingga rantai eksploitasinya putus apa pun konfigurasi aplikasinya. Kedua, setiap server dipindai untuk memeriksa kondisi 1 dan 2 pada konfigurasi maupun kode aplikasi.
Hasilnya: tidak ada aplikasi yang memenuhi syarat eksploitasi. Beberapa aplikasi memang mengubah handler sesi saat berjalan (kondisi 2), tetapi kondisi 1 tidak terpenuhi di mana pun, dan kondisi 3 sudah dimatikan. Lapisan pertahanan berganda seperti ini yang kami andalkan selama menunggu perbaikan resmi.
Hasil
Per 1 November 2026, 12 hari setelah perbaikan dirilis:
| Tingkat risiko | Aplikasi | Diperbarui | Dinonaktifkan | Terbuka |
| Critical | 21 | 15 | 6 | 0 |
| High | 20 | 18 | 2 | 0 |
| Medium | 7 | 7 | 0 | 0 |
| Total | 48 | 40 | 8 | 0 |
- Tidak ada aplikasi yang tersisa di versi PHP rentan. Semua aplikasi Critical tertangani, baik dengan patch, migrasi, maupun penonaktifan.
- Tidak ada aplikasi yang terdampak CVE-2026-115560, dan mitigasinya aktif di seluruh layanan publik.
- Sistem lama yang tidak dapat di-patch telah dipensiunkan, digantikan server baru dengan PHP 8.4 dan konfigurasi keamanan yang lebih ketat.
- Aplikasi berbasis kontainer kini mengunci versi PHP-nya, sehingga pembaruan berikutnya terkendali dan dapat ditelusuri.
Sebagai bagian dari penutupan, kredensial aplikasi pada sistem yang sebelumnya rentan telah dirotasi, dan log akses sejak sebelum pengumuman kerentanan telah diperiksa untuk mencari tanda-tanda percobaan eksploitasi.
Apa yang kami pelajari
Inventaris adalah kontrol keamanan. Kecepatan respons kami ditentukan oleh seberapa cepat kami tahu apa yang berjalan di mana. Inventaris yang dibuat untuk insiden ini sekarang dipelihara sebagai aset tetap, bukan dokumen sekali pakai.
Utang teknis adalah utang keamanan. Aplikasi yang tertinggal di versi PHP lama bukan hanya sulit dirawat; saat kerentanan kritis muncul, aplikasi itulah yang tidak punya jalan keluar cepat. Insiden ini mempercepat modernisasi yang sudah lama direncanakan.
Kunci versi, jangan ikuti tag. Image kontainer yang memakai tag mengambang membuat versi PHP yang berjalan bergantung pada kapan image terakhir dibangun. Mengunci versi membuat status keamanan bisa dibuktikan dari kode.
Verifikasi, jangan berasumsi. Nomor versi bisa menipu, restore tanpa error bisa tidak lengkap. Setiap langkah penting kami tutup dengan pemeriksaan yang hasilnya tercatat.
Matikan yang tidak dipakai. Aplikasi yang paling aman adalah aplikasi yang tidak lagi menyala. Delapan layanan pensiun dalam penanganan ini, dan kami kini meninjau daftar layanan secara berkala.
Langkah berikutnya
Pekerjaan ini belum sepenuhnya selesai, dan kami memilih untuk terbuka soal itu:
- Perbaikan resmi CVE-2026-115560. Mitigasi tetap aktif sampai PHP merilis perbaikannya; begitu tersedia, perbaikan akan diterapkan ke seluruh lingkungan dan dipindai ulang.
- Modernisasi berkelanjutan. Aplikasi yang masih bergantung pada perbaikan backport dijadwalkan untuk ditingkatkan ke versi PHP yang didukung penuh.
- Pemantauan. Peringatan keamanan PHP dan dependensi aplikasi dipantau secara rutin, dengan inventaris dan perangkat yang sudah ada sebagai titik awal respons berikutnya.
Kerentanan seperti PHP2Shell akan datang lagi. Yang bisa kami kendalikan adalah seberapa siap kami saat itu terjadi.
Referensi publik: pengumuman perbaikan PHP2Shell (Help Net Security), uraian teknis CVSS (Unit 42, Palo Alto Networks), mitigasi sementara (ma.ttias.be), dan pengumuman CVE-2026-115560 (The Hacker News).
