Mitigasi Log4j2 Vulnerability - Bagian 1
Pendahuluan
Untuk pendahuluan mengenai Vulnerability / Kerentanan Log4j2 ini bisa dilihat di artikel sebelumnya. link
Untuk penyebab Vulnerability / Kerentanan Log4j2 ini bisa dilihat di artikel sebelumnya. link
Memahami mengenai penyebab Vulnerabiliy / Kerentanan dari Log4j ini, akan sangat membantu kita dalam melakukan Mitigasi terhadap kasus ini.
Terjemahan bebas tentang Mitigasi dari Wikipedia
Mitigasi adalah tindakan yang diambil untuk mengurangi atau mengelola bahaya atau ancaman yang terjadi.
Jadi bagaimana Mitigasi untuk Log4j Vulnerability / Kerentanan Lo4j2 ini ?
Baik, pertama kali kita akan melihat apa yang paling berbahaya dari Log4j Vulnerability / Kerentanan Log4j ini.
Atau bagian mana dari code yang paling berbahaya dari Log4j Vulnerability ini.
Yang paling berbahaya adalah bagian sininya : JndiLookup.class:
Cara yang paling logis adalah bagaimana JndiLookup.class ini tidak dimasukkan dalam aplikasi ketika aplikasi Java kita berjalan, atau tidak bisa dijalankan fungsi lookup nya.
Dengan demikian ada 4 pilihan cara yang bisa kita lakukan :
- Buang class JndiLookup.class ini dari library kita.
- Jangan ikutkan library log4j2-core-xxx.jar di aplikasi kita.
- Setting konfigurasi on/off agar JndiLookup.class ini selalu off, sehingga fungsi lookup nya tidak berjalan.
- Pakai versi terbaru dari log4j2 yang sudah diperbaiki, yaitu versi >= 2.15.0. atau versi versi >= 2.16.0., yang secara default konfigurasinya akan memblok Lookup JNDI, akan tetapi dengan masih mempunyai konfigurasi untu bisa dipakainya fasilitas Lookup JNDI ini.
Sebenarnya secara sederhana, hanya itu saja, pilih salah satu dari 4 cara tersebut, dan persoalan Log4j2 Vulnerability ini akan selesai.
Tapi coba kita lihat apakah Mitigasi dari tiap-tiap cara tersebut bisa kita lakukan ?
1. Buang class JndiLookup.class ini dari library kita.
Cara ini merupakan cara paling primitif, dan cukup manual, tapi paling efektif.
Langsung menusuk ke jantung pertahanan dari Vulnerabilitynya ini.
Membutuhkan terminal command line untuk melakukan delete file JndiLookup.class yang terdapat dalam log4j2-core-xxx.jar.
Perintahnya :
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
Kemudian file log4j2-core-xxx.jar nya yang sudah kita hilangkan file JndiLookup.class itu bisa kita masukkan kembali sebagai library aplikasi kita.
Sudah, begitu saja.
Tetapi karena caranya yang primitif dan masih manual, maka cara ini hanya bisa dilakukan untuk aplikasi yang standalone, dan oleh Engineer yang terbiasa dengan import/export library secara manual.
Untuk aplikasi yang terdiri dari banyak service/microservice dan terdistribusi , maka cara ini akan merepotkan.
Harus cari *.jar nya, kemudian lakukan proses delete file JndiLookup.class didalamnya, lalu load secara local ke aplikasi kita.
Kalau terbiasa menggunakan dependency tools seperti maven, gradle, ivy, maka cara ini dianggap kuno dan nggak praktis.
Tetapi kalau terbiasa dengan perintah command line, maka bisa jadi tidak terlalu sulit.
2. Jangan ikutkan library log4j2-core-xxx.jar di aplikasi kita.
File JndiLookup.class berada di dalam package log4j2-core-xxx.jar.
Kalau kita mau hilangkan saja library ini gimana ? agar masalahnya hilang juga ?
Tentu saja tidak bisa , namanya saja sudah log4j2-core-xxx.jar, ada Core di nama librarynya.
Library ini adalah library utama ketika kita menggunakan Log4j2 logging framework.
Menghilangkan/exclude library ini artinya tidak usah saja memakai Log4j2 sebagai logging framework.
Jadi, cara ini tidak mungkin dilakukan.
Atau secara tidak langsung, cara ini artinya ganti saja logging framework nya pakai framework yang lain seperti Logback, Java Util Logging, dll.
3. Setting konfigurasi on/off agar JndiLookup.class ini selalu off, sehingga fungsi lookup nya tidak berjalan.
Nah ini mungkin cara yang efektif, tetapi harus hati-hati dan konsisten untuk melakukannya.
Semenjak Log4j2 release [2.10.0], sudah ada flag on/off untuk Lookup ini., tidak terbatas untuk JNDI saja.
Kalau kita lihat di codenya org.apache.logging.log4j.core.util.Constants
FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS = PropertiesUtil.getProperties().getBooleanProperty(log4j2.formatMsgNoLookups", false);
Defaultnya adalah False, artinya NOLOOKUP nya False, artinya secara default Log4j2 akan melakukan Lookup.
Penamaaan variablenya memang membingungkan.
Negatif x Negatif = Positif. . NoLookup x false = Lookup
Jadi tugas kita adalah menambahkan konfigurasi log4j2.formatMsgNoLookups=true.
Mitigasinya cukup dengan melakukan setting log4j2.formatMsgNoLookups=true
- bisa melalui JVM parameter ketika menjalankan perintah java
java -Dlog4j2.formatMsgNoLookups=true PocLog4j2-1.0.0.jar
- bisa di file .yml atau .application yang diacu sebagai property sistem.
log4j2.formatMsgNoLookups = true
Konfigurasi ini berarti meminta library Log4j2 untuk tidak melakukan Lookup terhadap parameter/message yang dipassing ke Log4j2., termasuk didalamnya lookup JNDI.
Karena flag on/off ini berlaku sejak versi Log4j2 2.10.0, maka cara ini berlaku kalau kita memakai versi Log4j2 dari versi 2.10.0 dan keatas.
Kekurangannya adalah kita tidak bisa melakukan cara ini di library Log4j2 versi 2.0-beta9 (dimana JNDILookup diperkenalkan) sampai dengan versi 2.9.1, karena belum ditambahkan flagnya ini.
Ada sebagian artikel yang menyarankan buat setting environment variable LOG4J_FORMAT_MSG_NO_LOOKUPS = true, akan tetapi sepertinya konfigurasi ini tidak ada di versi log4j2-core-2.14.0.jar yang saya gunakan.
Mungkin di versi sebelumnya ada, siapa tahu, boleh dicoba.
4. Pakai versi terbaru/patched dari log4j2 yaitu versi >= 2.15.0.
Cara ini adalah cara yang paling disukai dan banyak dipakai oleh orang.
Kita perlu merubah versi Log4j2 kita ke versi 2.15.0 atau 2.16.0, lalu build/packaging lagi aplikasi java kita, deploy ke server production, dan voilaaa.., semestinya vulnerability ini sudah tertangani.
Bagaimana cara merubah versinya itu :
- Konfigurasi di file terkait dependency management tools, seperti file .pom untuk maven, build.gradle untuk gradle, ivy.xml untuk ivy.
misalnya di .pom
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.16.0</version>
</dependency>
- Dowload manual versinya dari Log4j2 nya sendiri, dan attach ke library aplikasi kita.
Apa yang dilakukan oleh tim Log4j2 adalah hampir sama dengan cara nomor 3 diatas yaitu mengubah setting default value unt on/off Lookup, tetapi dengan beberapa tambahan konfigurasi lainnya agar lebih ketat ketika program kita memang ditujukan untuk melakukan koneksi JNDI.
Sebenarnya di versi Log4j2 2.15.0 keatas (termasuk 2.16.0), telah ditambahkan pula konfigurasi :
- log4j2.allowedLdapHosts , untuk mem-filter LDAP host mana saja yang diperbolehkan.
- log4j2.allowedLdapClasses, untuk mem-filter LDAP class mana saja yang diperbolehkan.
- log4j2.allowedJndiProtocols, untuk mem-filter JNDI protocol mana saja yang diperbolehkan, apakah rmi, ldap, ldaps, dll.
di tiap konfigurasi tersebut kita bisa menambahkan host, class ldap, atau protokol yang kita izinkan saja.
Kita lanjut lagi dengan apa saja Mitigasi lainnya yang bisa dilakukan selain modifikasi terkait library Log4j2 nya.