Pada episode ini kita membedah ImageTragick, kerentanan eksekusi kode jarak jauh yang mengguncang ImageMagick di 2016. Kita menelusuri akar masalahnya, mempelajari pelajaran bertahan yang lahir darinya, dan membangun kebiasaan aman dalam memproses input yang tidak dipercaya.

Di episode 13 kalian memasang whitelist coder dan limit resource di policy.xml. Kalau terasa berlebihan, episode ini akan menjelaskan kenapa langkah itu bukan paranoia — melainkan buah pahit dari peristiwa nyata. Pada 2016, dunia menemukan bahwa ImageMagick, tool yang ada di hampir setiap server web, bisa ditaklukkan hanya dengan mengunggah sebuah gambar.
Episode 14 membedah ImageTragick (CVE-2016-3714): bagaimana serangannya bekerja, mengapa desain ImageMagick membuatnya mungkin, dan — yang paling penting — kebiasaan apa yang harus kalian pegang selama bertahun-tahun sesudahnya. Ini episode tentang keamanan bukan sebagai kumpulan perintah, melainkan sebagai cara berpikir.
ImageTragick adalah nama serangkaian kerentanan di ImageMagick yang memungkinkan Remote Code Execution (RCE) — penyerang yang hanya bisa mengunggah file gambar bisa menjalankan perintah apa pun di server. Nama resminya CVE-2016-3714, ditemukan oleh peneliti dari Slack.
Ini bukan bug memori yang rumit. Akar masalahnya ada pada dua coder yang dirancang untuk kekuatan, bukan keamanan:
Keduanya adalah bahasa, bukan sekadar format. Dan karena ImageMagick mengikuti kata "file" yang dikirim, sebuah file dengan header gambar palsu yang berisi sintaks MVG bisa membuat ImageMagick mengeksekusi perintah sistem. Inilah inti masalahnya: format yang seharusnya mendeskripsikan gambar, ternyata bisa mendeskripsikan eksekusi.
Serangan klasik ImageTragick terlihat tidak berbahaya dari luar. Sebuah file dengan ekstensi .mvg berisi sintaks yang memicu eksfiltasi data:
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg"|ls -la")'
pop graphic-contextBaca dengan teliti: sintaks url(...) di MVG bisa menerima sumber eksternal. Dengan menyisipkan tanda kutip dan karakter | (pipe), penyerang "memutuskan" string URL dan menjalankan perintah sistem — di sini ls -la sebagai bukti konsep. Versi produksinya mengganti ls dengan perintah yang lebih berbahaya: membaca file rahasia, memasang backdoor, atau mencuri kredensial.
Ketika server web memproses unggahan pengguna dengan ImageMagick untuk membuat thumbnail — pola yang ada di ribuan aplikasi — satu file .mvg sudah cukup untuk menjadikan server milik penyerang. Tidak ada langkah "mengeksploitasi kernel" atau "meretas database" — pintunya sudah terbuka sejak format yang tidak terduga diterima dengan tangan terbuka.
ImageTragick bukan hasil kelalaian satu orang — ia adalah konsekuensi desain. ImageMagick tumbuh sebagai tool serba bisa untuk orang yang memproses file mereka sendiri. Di era itu, "membaca apa pun" adalah fitur, bukan bug. Dunia kemudian berubah: ImageMagick dipindahkan ke server untuk memproses input dari pengguna yang tidak dikenal, tanpa mengubah asumsi dasarnya.
Ini pelajaran pertama dan terpenting: asumsi keamanan sebuah tool ditentukan oleh lingkungan asalnya, bukan oleh cara kita memakainya. Tool yang aman untuk file pribadi di laptop belum tentu aman untuk unggahan pengguna di server. Mengangkat tool dari satu konteks ke konteks lain tanpa menilai ulang asumsinya adalah sumber kerentanan paling sering di dunia nyata.
Respons yang benar terhadap ImageTragick bukan "menghindari ImageMagick", melainkan mengubah cara kerja. Empat kebiasaan berikut adalah warisan langsung dari peristiwa ini:
1. Jangan pernah memproses input tak dikenal tanpa batas. policy.xml dari episode 13 adalah lantai wajib. Whitelist coder, batasi resource, tutup coder yang bisa mengeksekusi — MVG dan MSL mati sejak awal.
2. Validasi sebelum memproses, bukan sesudah. Cek tipe file di sisi server dengan mendeteksi magic bytes, bukan ekstensi:
file --brief --mime-type upload.datfile membaca signature di awal file, bukan nama file. Kalau aplikasi kalian hanya menerima JPEG, periksa bahwa byte pertama benar-benar JPEG — dan tolak yang lain sebelum ImageMagick menyentuhnya.
3. Sanitasi nama file. Nama file yang datang dari pengguna tidak pernah bisa dipercaya:
SAFE=$(basename "$USER_INPUT" | tr -cd '[:alnum:]_.-' | head -c 64)
magick "$USER_INPUT" "/var/media/$SAFE.jpg"basename membuang direktori, tr -cd menghapus semua karakter selain huruf, angka, titik, underscore, dan dash. Sebuah nama file tidak boleh bisa menjadi path lain atau perintah lain — menertibkan karakter itu menutup satu kelas serangan sebelum mulai.
4. Pisahkan privilege. Jalankan ImageMagick sebagai user yang tidak punya akses ke hal-hal berharga. Process yang berjalan sebagai www-data dengan akses penuh ke filesystem adalah mimpi buruk; process yang berjalan dalam container tanpa shell adalah target yang tidak menarik.
Warning
ImageMagick bukan satu-satunya yang pernah diserang lewat format gambar — pustaka seperti libjpeg, libpng, dan Ghostscript punya riwayat CVE mereka sendiri. Kebiasaan validasi dan pemisahan privilege di atas berlaku untuk seluruh pipeline, bukan hanya satu tool.
Banyak distribusi merespons ImageTragick dengan mengirimkan policy.xml yang lebih ketat secara default. Sebagai praktik, file kalian sebaiknya berisi kebijakan yang mirip:
<policymap>
<policy domain="coder" rights="none" pattern="MVG"/>
<policy domain="coder" rights="none" pattern="MSL"/>
<policy domain="coder" rights="none" pattern="HTTPS"/>
<policy domain="coder" rights="none" pattern="URL"/>
<policy domain="coder" rights="none" pattern="EPHEMERAL"/>
<policy domain="coder" rights="read|write" pattern="PNG"/>
<policy domain="coder" rights="read|write" pattern="JPEG"/>
<policy domain="coder" rights="read|write" pattern="WEBP"/>
<policy domain="resource" name="memory" value="256MiB"/>
<policy domain="resource" name="disk" value="1GiB"/>
<policy domain="resource" name="time" value="60"/>
</policymap>Perhatikan baris-baris rights="none" di atas: MVG, MSL, HTTPS, URL, dan EPHEMERAL adalah coder yang membuka kemampuan membaca dari sumber tidak terduga atau mengeksekusi perintah. Mematikannya langsung menutup jalan serangan yang diketahui. Ini persis kebijakan yang dirangkum di episode 13, disusun berdasarkan bukti nyata.
ImageTragick juga mengajarkan pelajaran operasional yang lebih luas: keamanan adalah fungsi waktu. CVE-2016-3714 diperbaiki di versi rilis, tapi kerentanan lain muncul di tahun-tahun berikutnya — dan setiap distribusi mengikuti jadwal pembaruan yang berbeda.
Tiga aturan pembaruan yang harus dipegang:
magick -version | head -1Jalankan magick -version dan catat hasilnya. Sekarang ketahui: versi yang sama yang dipakai kemarin adalah versi yang sama yang bisa diserang hari ini, jika sudah ada CVE baru dan kalian belum memperbarui.
Tip
Biasakan mengecek kebijakan aktif sebelum memproses input apapun: magick -list policy menampilkan semua kebijakan yang berlaku saat ini. Ini pemeriksaan 5 detik yang bisa menyelamatkan hari — verifikasi bahwa MVG dan MSL benar-benar berstatus none sebelum pipeline berjalan.
ImageTragick adalah studi kasus tentang bagaimana satu asumsi desain yang sudah kuno bisa menjadi pintu masuk bagi serangan modern. Kebiasaan yang lahir darinya berlaku jauh melampaui ImageMagick:
Pola pikir inilah yang akan kalian bawa ke episode 15, ketika ImageMagick belajar berkomunikasi dengan dunia luar — membaca gambar dari URL. Kemampuan itu membuka pintu ke jenis serangan yang berbeda: SSRF.
Episode 14 membedah ImageTragick sebagai studi kasus keamanan paling berpengaruh dalam sejarah ImageMagick: akar masalahnya pada coder MVG dan MSL yang bisa mengeksekusi perintah, anatomi serangan lewat sintaks url(...), pelajaran bertahan tentang validasi input, sanitasi nama file, dan pemisahan privilege, konfigurasi policy.xml pasca-insiden, serta disiplin pembaruan versi.
Inti yang perlu diingat: kerentanan jarang lahir dari kekurangan — ia lahir dari kelebihan yang tidak dijaga. ImageMagick tidak pernah "menjadi" berbahaya; ia selalu punya kemampuan yang sama, dan kemampuan itulah yang disalahgunakan ketika dipakai tanpa batas di lingkungan yang tidak sesuai asumsinya.
Sampai jumpa di episode 15, ketika kita membawa pelajaran ini ke ujian berikutnya: I/O jarak jauh lewat URL.