XML-RPC WordPress: 3 Cara Menonaktifkannya & Cara Mengenali Serangan xmlrpc.php | Pengecualian Jetpack

Jika log akses situs web WordPress menunjukkan ratusan permintaan xmlrpc.php beruntun dari IP yang sama, itu adalah serangan penebakan kata sandi yang mengincar XML-RPC WordPress. Sebanyak 8,624 entri log akses dalam sehari dari server Nginx + Apache yang menjalankan beberapa situs WordPress dipilah, lalu tiga cara menonaktifkannya diterapkan langsung dan kode responsnya diperiksa. Hasilnya dirangkum di sini: di lapisan mana pemblokiran harus dilakukan agar eksekusi PHP pun ikut berkurang.
XML-RPC adalah protokol yang bertukar dokumen XML lewat HTTP untuk memanggil fungsi WordPress dari jarak jauh. Sejak WordPress 3.5, opsi untuk menyalakan dan mematikannya di layar pengaturan sudah dihapus, sehingga XML-RPC sudah aktif sejak WordPress baru dipasang.
1️⃣ Peran xmlrpc.php dan Siapa yang Memakainya
Sejak REST API hadir, [xmlrpc.php] mudah dianggap sebagai file yang tidak dipakai lagi, padahal sampai sekarang Jetpack masih menghubungkan situs dengan WordPress.com lewat file ini. Dokumentasi resmi Jetpack menyebutkan dengan jelas bahwa Jetpack bergantung pada koneksi XML-RPC, dan di hosting yang memblokir XML-RPC secara default, koneksi Jetpack itu sendiri gagal. Ibaratnya kantor yang sampai sekarang masih menyimpan satu nomor faks.
Per WordPress 7.1, file ini menerima 77 metode: 50 metode keluarga wp yang menangani pos, media, dan komentar; 23 metode protokol blog lama (MetaWeblog, MovableType, Blogger); 2 metode pingback; serta 2 metode demo untuk pengujian.
Keluarga wp login dengan nama pengguna dan kata sandi yang dimuat di body permintaan, sehingga tidak melewati layar login. Menulis dan menyunting pos, mengunggah media, dan mengelola komentar semuanya termasuk keluarga ini, sedangkan 23 metode protokol blog lama dipertahankan agar pos bisa dipertukarkan dengan cara yang sama seperti alat blog lain.
demo.sayHello adalah panggilan uji yang ada di XML-RPC WordPress. Jika dikirim, ia hanya membalas satu kata, [Hello!]; karena tidak perlu login, panggilan ini dipakai untuk mengecek apakah XML-RPC berfungsi. Pasangannya adalah demo.addTwoNumbers, yang menjumlahkan dua angka lalu mengembalikan hasilnya.
Semuanya hanya merespons jika body XML dikirim lewat POST; jika alamatnya dibuka di browser, muncul pesan [XML-RPC server accepts POST requests only.] bersama kode 405.
Pingback juga menjadi tugas file ini. Saat pos diterbitkan, pingback dikirim ke xmlrpc.php milik situs yang ditautkan di isi pos, dan server penerima membuka sendiri URL pengirim untuk memastikan tautannya benar-benar ada.
2️⃣ Serangan xmlrpc.php di Log Akses
Penebakan kata sandi tidak melewati layar login, melainkan masuk lewat [xmlrpc.php]. Di log akses server Nginx + Apache yang menjalankan beberapa situs WordPress, dari pukul 00.00 sampai 20.00 pada 14 Oktober tercatat 8,624 permintaan POST /xmlrpc.php dari 72 IP, dan 19 IP di antaranya masing-masing mengirim tepat 300 permintaan.
Satu IP mengirim 300 permintaan selama 28 menit, dari pukul 14.09 sampai 14.37, dengan jeda 5–6 detik yang tetap sampai akhir. Sebanyak 8,524 permintaan masuk dengan Jetpack atau WordPress.com tertulis di User-Agent, dan IP yang sama bergantian memakai beberapa nilai yang meniru format Jetpack asli, seperti [Jetpack by WordPress.com (Jetpack 13.0; WordPress 6.3)].
Pada hari yang sama, sebelum pukul 14.00, fitur mematikan XML-RPC di plugin keamanan mengembalikan permintaan ini ke beranda dengan 302; setelah pukul 14.00, begitu diblokir di Nginx, permintaan berakhir dengan 403. Kode 302 berarti PHP dijalankan untuk setiap permintaan meski body-nya 0 byte, sedangkan 403 adalah respons yang tidak melewati PHP.
3️⃣ system.multicall dan Penebakan Kata Sandi
Banyak penjelasan menyebut bahwa dengan [system.multicall], satu permintaan bisa mencoba ratusan kata sandi, tetapi begitu login gagal sekali dalam satu permintaan, WordPress tidak lagi mencocokkan kata sandi pada panggilan sisanya. Hanya panggilan pertama yang melewati wp_authenticate; panggilan berikutnya langsung dijawab dengan error yang sama, [Incorrect username or password.], tanpa pemeriksaan.
Respons tetap kembali sebanyak jumlah panggilan, sehingga satu permintaan berisi 100 kata sandi salah mendapat 100 error dalam respons 23KB hanya dalam 0.12 detik. Jika kata sandi yang benar diletakkan di belakang dalam permintaan yang sama, ia ikut ditolak karena kegagalan panggilan sebelumnya; jika diletakkan di depan, hanya panggilan itu yang berhasil. Pencocokan kata sandi hanya terjadi sekali, tetapi penguraian XML dan pemuatan WordPress berulang di setiap permintaan, jadi beban server dari serangan ini berasal dari jumlah permintaan itu sendiri, bukan dari pemeriksaan login.
4️⃣ 3 Cara Menonaktifkan XML-RPC dan Kode Responsnya
Meski XML-RPC dimatikan di plugin, permintaan [xmlrpc.php] tetap sampai ke PHP. Saat dimatikan dengan filter, permintaan berisi 100 panggilan pun tetap dibalas HTTP 200 dengan 100 error (24KB). Menurut lapisan yang menolak permintaan, caranya terbagi menjadi tiga, dan kode responsnya berbeda-beda.
1. Mematikan lewat kode dengan filter xmlrpc_enabled
Cukup tambahkan satu baris add_filter yang membuat filter [xmlrpc_enabled] bernilai false ke functions.php milik tema. Dalam kondisi ini, panggilan yang perlu login ditolak dengan error [XML-RPC services are disabled on this site.] dan HTTP 405, tetapi panggilan uji demo.sayHello yang tidak perlu login tetap merespons dengan 200.
2. Mematikan lewat pengaturan plugin: Perfmatters·Hide My WP
Ini cara menonaktifkannya lewat pengaturan Disable XML-RPC di plugin seperti Perfmatters dan Hide My WP. Hide My WP memakai cara filter yang sama seperti di atas sehingga responsnya pun sama, tetapi Perfmatters, selain memakai filter yang sama, juga mengakhiri permintaan langsung ke [xmlrpc.php] dengan 403 serta menghapus header pingback dan tautan pingback, sehingga setelah dimatikan, GET maupun POST sama-sama dijawab 403. Namun, untuk menghasilkan 403 itu WordPress tetap berjalan sampai tahap init, sehingga respons memakan 0.13–0.15 detik, sama seperti saat terbuka, dan beban PHP tetap ada.
3. Memblokir di server web: Nginx·Apache
Baik Nginx maupun Apache menolak permintaan sebelum sampai ke PHP, sehingga berbeda dengan cara plugin, WordPress tidak dijalankan.
# Nginx — di dalam blok server, di atas location pemrosesan PHP
location = /xmlrpc.php {
deny all;
}Blok location ini diletakkan di atas location pemrosesan PHP, dan Nginx langsung menolak permintaan yang persis cocok dengan [xmlrpc.php]. Setelah ditambahkan, periksa konfigurasinya lalu muat ulang (reload) agar diterapkan.
nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulsystemctl reload nginxSetelah dimuat ulang, GET dan POST berakhir dengan 403 tanpa sampai ke PHP; body respons adalah halaman 403 bawaan Nginx sebesar 153 byte, dan respons hanya memakan 0.02 detik.
# Apache — .htaccess di root situs (Apache 2.4)
<Files xmlrpc.php>
Require all denied
</Files>Di server yang hanya memakai Apache, cukup masukkan direktif Files di atas ke .htaccess di root situs dan langsung berlaku; halaman 403 bawaan Apache (199 byte) kembali dalam 0.02 detik yang sama.
curl -s -o /dev/null -w '%{http_code}' -X POST https://example.com/xmlrpc.php -d '<methodCall><methodName>demo.sayHello</methodName></methodCall>'403Perintah di atas mengirim panggilan uji demo.sayHello lewat POST untuk memeriksa kode respons; setelah diblokir di server web, yang kembali adalah 403. Jika dikirim tanpa opsi [-o /dev/null] dan [-w], body-nya terlihat: jika muncul [Hello!], berarti masih terbuka. Situs yang dimatikan hanya dengan filter pun memberi respons yang sama, jadi panggilan login juga harus dikirim untuk memastikan 405.
5️⃣ Kapan Tidak Boleh Dimatikan dan Alternatifnya
Memblokir sepenuhnya di server web adalah cara yang paling ampuh, tetapi tidak cocok untuk situs yang terhubung ke WordPress.com lewat Jetpack. Jetpack bergantung pada koneksi XML-RPC, dan di hosting yang memblokir XML-RPC secara default seperti WP Engine, pengecualian harus dibuka sesuai panduan Jetpack agar bisa terhubung. Hal yang sama berlaku untuk situs yang ingin menerima pingback.
Untuk situs seperti ini, aksesnya dipersempit dengan hanya mengizinkan daftar IP yang dipublikasikan Jetpack (jetpack.com/ips-v4.txt) dan menolak sisanya. Di dalam blok location Nginx, tambahkan baris allow sebanyak rentang IP-nya, lalu letakkan deny all di bagian akhir.
Jika tidak bisa memblokirnya sepenuhnya, masih ada cara membatasi jumlah permintaan per menit untuk permintaan yang belum login. Pengaturannya sama dengan bagian pembatasan laju Nginx di artikel Keamanan wp-admin dan hanya menghitung permintaan tanpa cookie login, sehingga pekerjaan admin yang sudah login tidak terpengaruh.
🔢 FAQ & Konten yang Direkomendasikan










ℹ️ Pemberitahuan Afiliasi
Konten di situs ini berisi tautan afiliasi. Jika pengunjung membeli produk atau layanan melalui tautan tersebut, situs ini menerima komisi dari penjual. Harga yang dibayar pembeli(turun saat ada diskon promo ↓), tidak naik karena hal ini. Harga, diskon, dan informasi stok yang ditampilkan berlaku pada saat penulisan dan bisa berbeda dengan kondisi sebenarnya, jadi pastikan kembali di situs penjual sebelum membeli. Pemilihan dan penilaian produk dibuat berdasarkan standar kami sendiri, dan ada tidaknya komisi tidak memengaruhi urutan maupun isi penilaian.