.php.jpg), null-byte injection, atau manipulasi MIME type multipart. Masalah struktural sebenarnya berada di level arsitektur Linux: proses PHP-FPM berjalan menggunakan user yang sama (www-data) dengan pemilik hak tulis direktori, sekaligus memiliki kewenangan untuk memanggil interpreter PHP pada file apa pun yang berhasil ditulis ke storage. Selama interpreter diizinkan mengeksekusi apa yang bisa ditulisnya sendiri (write XOR execute violation), webroot Anda hanyalah bom waktu.
Membalik Paradigma dengan Immutable Container Rootfs
/var/www/html menjadi immutable. Jika penyerang mengeksploitasi fungsi file_put_contents() pada controller aplikasi warisan, kernel Linux akan langsung melempar error EROFS (Read-only file system). Seluruh dependensi, vendor libraries, dan script PHP dipanggang saat proses image build berlangsung di pipeline CI/CD, bukan ditarik secara dinamis di server produksi.
YAML
services:
php-fpm:
image: app-runtime:latest
read_only: true
tmpfs:
- /tmp:rw,noexec,nosuid,size=64m
volumes:
- storage_uploads:/var/www/html/public/uploads:rwtmpfs dalam RAM dengan batas kapasitas ketat serta flag noexec agar payload biner tidak dapat dieksekusi dari /tmp.
Jebakan Eksekusi Interpreter dan Batasan Mount Noexec
noexec (mount -o noexec,nosuid,nodev ...) sudah cukup untuk mencegah eksekusi webshell. Di sinilah letak kesalahpahaman fundamental mengenai cara kerja kernel Linux versus interpreter userspace. Flag noexec di level kernel hanya memblokir system call execve(), yang berarti kernel menolak memuat biner ELF executable dari blok penyimpanan tersebut. Namun, PHP-FPM bukanlah biner yang dieksekusi dari dalam folder upload; PHP-FPM adalah interpreter yang sudah berjalan di memori dan hanya melakukan syscall open() serta read() terhadap file .php.
Artinya, meskipun partisi upload dipasang dengan flag noexec, script webshell tetap dapat diparse dan dieksekusi secara sempurna jika PHP-FPM diarahkan untuk membaca file tersebut. Oleh karena itu, proteksi filesystem harus dikombinasikan dengan pemutusan jalur delegasi FastCGI pada web server reverse proxy (Nginx). Nginx harus dikonfigurasi secara eksplisit agar tidak pernah meneruskan request path /uploads/ ke socket FastCGI milik PHP-FPM, melainkan hanya menyajikannya sebagai static asset mentah atau langsung memblokir ekstensi interpreter.
NGINX
location ^~ /uploads/ {
location ~ \.(php|phar|phtml|sh|py|pl|cgi)$ {
deny all;
return 404;
}
try_files $uri =404;
}^~ pada Nginx memberikan prioritas pencocokan prefix di atas regular expression lainnya. Bila ada permintaan URL yang merujuk ke direktori upload dan mengandung ekstensi script berbahaya, koneksi langsung diputus sebelum sempat menyentuh socket FastCGI di backend.
Mengisolasi Ruang Gerak Syscall dengan AppArmor
php-fpm untuk men-spawn sub-process shell seperti /bin/sh atau /bin/bash.
Secara default, jika penyerang sukses mengeksekusi fungsi PHP berbahaya seperti system(), exec(), atau passthru(), PHP-FPM akan memanggil execve ke binary shell bawaan sistem operasi. Dengan membuat profil AppArmor khusus untuk daemon PHP-FPM, kita dapat mendefinisikan whitelist path file yang boleh diakses dan secara eksplisit menolak eksekusi shell. Menutup fungsi ini di php.ini via disable_functions sering kali tidak cukup karena penyerang berpengalaman dapat melakukan bypass menggunakan binary library yang ter-load via FFI atau eksploitasi modul C.
Dengan membatasi kapabilitas syscall pada level kernel melalui AppArmor dan menerapkan boundary yang tegas antara direktori statis dan pipeline eksekusi dinamis, serangan defacement judi online yang memanfaatkan kelemahan CMS warisan dapat dinetralisasi sepenuhnya tanpa harus merombak jutaan baris kode aplikasi lama.