Banyak pemilik situs WordPress berkenalan dengan XML-RPC lewat jalan yang tidak menyenangkan. Laporan mingguan plugin keamanan menyebut sebuah berkas bernama xmlrpc.php diketuk ratusan kali dari alamat yang berganti-ganti. Atau penyedia hosting mengirim pemberitahuan bahwa berkas itu memicu lonjakan penggunaan CPU. Namanya terdengar asing, padahal berkas tersebut sudah ada di setiap instalasi WordPress selama belasan tahun.

XMLRPC adalah protokol yang memungkinkan sebuah program memanggil fungsi di komputer lain lewat internet, dengan XML sebagai cara menuliskan pesan dan HTTP sebagai kendaraannya. Di WordPress, protokol itu diwujudkan sebagai satu berkas di akar instalasi. Artikel ini membedah apa yang sebenarnya dikerjakan berkas tersebut, seberapa nyata risikonya hari ini, dan bagaimana menutupnya tanpa merusak hal lain yang masih Anda pakai.

Apa Itu XMLRPC?

XML-RPC adalah singkatan dari XML Remote Procedure Call. Gagasannya sederhana: sebuah aplikasi mengirim pesan berisi nama fungsi beserta parameternya ke server lain, server menjalankan fungsi tersebut, lalu mengirim balik hasilnya. Yang membedakannya dari cara lain adalah pesan itu ditulis dalam format XML dan dikirim sebagai permintaan HTTP POST biasa.

Istilah remote procedure call sendiri berarti memanggil prosedur dari jarak jauh. Bagi program pemanggil, hasilnya terasa seolah ia menjalankan fungsi lokal, padahal pekerjaan sesungguhnya terjadi di mesin lain. Konsep inilah yang belakangan berkembang menjadi bermacam bentuk API yang kita pakai sekarang.

Protokol ini bukan barang baru. XML-RPC dirancang pada 1998 oleh Dave Winer dari UserLand Software bersama Microsoft, dan implementasi pertamanya hadir di UserLand Frontier 5.1 pada Juni tahun yang sama. Dokumen spesifikasi resminya bertanggal 15 Juni 1999 dan panjangnya hanya beberapa halaman. Kesederhanaan itu disengaja, dan justru karena terlalu sederhana untuk kebutuhan korporasi, penerusnya kemudian dikembangkan menjadi SOAP. Gagasan yang sama juga melahirkan JSON-RPC yang menukar XML dengan JSON, dan belakangan gRPC yang jauh lebih cepat karena tidak lagi mengirim teks.

Anatomi Satu Panggilan XML-RPC

Cara tercepat memahami protokol ini adalah melihat pesannya langsung. Setiap permintaan dibungkus elemen methodCall yang berisi nama fungsi dan daftar parameter. Berikut panggilan paling sederhana yang dikenal semua server XML-RPC:

HTML
<?xml version="1.0"?>
<methodCall>
  <methodName>demo.sayHello</methodName>
  <params></params>
</methodCall>

Server membalas dengan methodResponse berisi nilai kembaliannya. Balasan di bawah ini bukan contoh karangan, melainkan keluaran nyata saat permintaan tadi dikirim ke wordpress.org/xmlrpc.php:

HTML
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
  <params>
    <param>
      <value><string>Hello!</string></value>
    </param>
  </params>
</methodResponse>

Nilai yang boleh dikirim dibatasi enam tipe dasar, yaitu bilangan bulat (int atau i4), boolean, string, double, tanggal dateTime.iso8601, dan data biner base64. Untuk data bertingkat tersedia struct yang menyimpan pasangan nama dan nilai, serta array yang menyimpan daftar nilai. Kalau terjadi kesalahan, server tidak mengirim params melainkan elemen fault berisi faultCode berupa angka dan faultString berupa keterangan.

Anatomi pesan XML-RPC: permintaan methodCall memanggil demo.sayHello, balasan methodResponse mengembalikan string Hello.Anatomi pesan XML-RPC: permintaan methodCall memanggil demo.sayHello, balasan methodResponse mengembalikan string Hello.

Perhatikan bahwa tidak ada URL berbeda untuk tiap fungsi. Seluruh panggilan menuju satu alamat yang sama, dan nama fungsinya ditulis di dalam badan pesan. Inilah perbedaan mendasar dengan REST API, yang justru menaruh identitas sumber daya di URL-nya.

Peran xmlrpc.php di Dalam WordPress

Di setiap instalasi WordPress terdapat berkas xmlrpc.php di folder paling atas, sejajar dengan wp-config.php. Berkas itu adalah satu-satunya pintu masuk XML-RPC. Isinya sendiri pendek, hanya sekitar tiga kilobyte, karena tugas beratnya diserahkan ke kelas lain di dalam wp-includes.

Pintu tersebut melayani tujuh keluarga fungsi. Keluarga wp. berisi fungsi asli WordPress untuk mengelola pos, halaman, media, komentar, kategori, dan pengguna. Keluarga blogger., metaWeblog., dan mt. adalah warisan kompatibilitas dengan Blogger, MetaWeblog, dan Movable Type. Sisanya pingback. untuk tautan antarblog, demo. untuk pengujian, dan system. untuk fungsi bawaan protokol.

Saat diperiksa pada instalasi yang benar-benar berjalan, jumlah fungsi yang tersedia mencapai 79 buah. Sebanyak 66 di antaranya menuntut nama pengguna dan kata sandi sebelum bisa dijalankan. Sisanya, termasuk pingback.ping dan system.multicall, dapat dipanggil siapa saja tanpa login sama sekali. Angka terakhir inilah yang menjelaskan sebagian besar cerita di section berikutnya.

Satu hal penting soal sejarahnya: sampai WordPress 3.4, XML-RPC punya tombol nyala-mati di halaman pengaturan. Mulai WordPress 3.5 yang rilis 11 Desember 2012, protokol ini aktif secara bawaan dan tombol tersebut dihapus. Sejak saat itu mematikannya membutuhkan kode atau bantuan plugin.

Untuk Apa XML-RPC Masih Dipakai

Kegunaan aslinya adalah menerbitkan tulisan dari luar dasbor. Pada masa koneksi internet masih lambat dan mahal, orang menulis di aplikasi desktop secara offline, lalu mengirimkannya sekaligus ketika terhubung. Aplikasi seperti Windows Live Writer bekerja persis dengan cara ini.

Pemakaian yang masih hidup sampai sekarang ada empat. Aplikasi WordPress di ponsel memakai XML-RPC untuk menyambung ke situs yang Anda kelola sendiri tanpa perantara. Jetpack membutuhkannya untuk membangun koneksi ke WordPress.com, dan koneksi itu memakai token, bukan pengiriman kata sandi. Pingback dan trackback antarblog berjalan lewat fungsi pingback.ping. Terakhir, sejumlah plugin lawas memakainya untuk sinkronisasi konten.

Di luar WordPress, protokol ini juga belum benar-benar pensiun. Modul xmlrpc.client masih menjadi bagian pustaka standar Python sampai versi 3.14. Dokumentasi resminya memberi peringatan bahwa modul itu tidak aman menghadapi data yang sengaja dirancang jahat. Perangkat firewall pfSense dan OPNsense memakainya untuk menyelaraskan konfigurasi antar-mesin.

Sebagai perbandingan yang menarik, Drupal menyertakan XML-RPC di intinya sampai versi 7, lalu mengeluarkannya menjadi modul tambahan pada Drupal 8. Alasannya, tidak ada lagi bagian inti yang memakainya. WordPress mengambil keputusan berbeda dan mempertahankannya demi kompatibilitas mundur, dengan konsekuensi yang harus ditanggung setiap pemilik situs sampai hari ini.

Kenapa XML-RPC Jadi Sasaran Empuk

Ada tiga alasan struktural yang membuat berkas ini disukai penyerang. Yang sering disebut sebagai XML-RPC exploit sebenarnya bukan celah keamanan dalam arti biasa, melainkan penyalahgunaan fitur yang memang dirancang terbuka.

Pertama, ia melewati halaman login sepenuhnya. Semua lapisan pengaman yang Anda pasang di wp-login.phpCAPTCHA, pembatasan jumlah percobaan, sampai autentikasi dua faktor — tidak berlaku di jalur ini. Autentikasi XML-RPC berlangsung tanpa interaksi manusia, sehingga tidak ada tempat untuk menyisipkan uji tambahan.

Kedua, fungsi system.multicall pernah melipatgandakan efisiensi serangan. Fungsi ini membungkus banyak panggilan dalam satu permintaan HTTP. Sebuah laporan keamanan pada Oktober 2015 mencatat sampai 1.999 percobaan kata sandi dimuat dalam satu permintaan, dengan wp.getCategories sebagai fungsi yang paling sering dipakai. Serangan brute force yang biasanya menghasilkan ribuan baris log berubah menjadi hanya beberapa baris.

Ketiga, pingback.ping bisa disuruh menembak situs orang lain. Karena fungsi ini tidak butuh login, siapa pun dapat meminta situs Anda mengambil sebuah URL. Pada Maret 2014, lebih dari 162.000 situs WordPress yang bersih dan tidak diretas dipakai bersamaan sebagai penguat serangan DDoS terhadap satu korban. Pemilik situs-situs itu tidak menyadari apa pun selain tagihan trafik yang membengkak.

Yang Sudah Berubah Sejak 2015

Dua dari tiga alasan di atas kondisinya sudah berubah sejak laporan-laporan tadi terbit. Ada empat tonggak yang layak Anda ketahui sebelum mengambil keputusan.

WordPress 4.4 (8 Desember 2015) mematahkan penguatan lewat system.multicall. Kode intinya kini menandai satu instance server begitu ada satu autentikasi gagal. Setelah tanda itu menyala, seluruh percobaan login berikutnya dalam permintaan yang sama otomatis ditolak tanpa diperiksa. Memuat 1.999 kata sandi dalam satu permintaan sekarang hanya menghasilkan satu percobaan nyata dan 1.998 penolakan langsung.

WordPress 4.7 (6 Desember 2016) memasukkan REST API ke inti. Sejak versi ini WordPress punya jalur resmi berbasis JSON yang lebih ringan dan bisa dilindungi berlapis. Hampir seluruh alat modern, termasuk editor Gutenberg, sudah pindah ke jalur tersebut. Jalur itu pula yang dipakai saat WordPress dijalankan secara headless, yakni sebagai backend konten yang tampilannya dibangun terpisah.

Perbedaan XML-RPC vs REST API paling mudah dilihat berdampingan:

XML-RPCREST API
Alamat/xmlrpc.php/wp-json/
Format pesanXMLJSON
Masuk intiWordPress 3.5WordPress 4.7
Penentu tindakannama fungsijalur URL
Dipakai editor bloktidakya

WordPress 5.6 (8 Desember 2020) memperkenalkan Application Password. Anda dapat membuat kata sandi khusus aplikasi sepanjang 24 karakter acak yang berlaku untuk REST API sekaligus XML-RPC. Kekuatan tebakannya setara 142 bit, jauh di atas ambang 128 bit yang dianggap aman. Kata sandi akun asli Anda tidak perlu lagi diketik ke aplikasi mana pun, dan satu kata sandi aplikasi dapat dicabut sendirian tanpa mengganggu yang lain.

Usulan lanjutan sedang dibahas di inti WordPress. Sebuah tiket pengembangan mengusulkan agar autentikasi XML-RPC hanya boleh memakai Application Password dan menolak kata sandi akun biasa. Alasan yang diajukan persis alasan pertama di section sebelumnya: jalur non-interaktif tidak bisa dilindungi 2FA, CAPTCHA, maupun pembatasan laju. Usulan itu masih berstatus menunggu tinjauan, jadi belum berlaku.

Yang tidak berubah adalah penyalahgunaan pingback.ping. Fungsi itu tetap terbuka tanpa login, dan pihak WordPress sejak awal memperlakukannya sebagai fitur bawaan, bukan celah yang perlu ditambal.

Lima tonggak XML-RPC di WordPress: aktif bawaan sejak 3.5, multicall ditutup 4.4, REST API 4.7, pingback terbuka 7.1.Lima tonggak XML-RPC di WordPress: aktif bawaan sejak 3.5, multicall ditutup 4.4, REST API 4.7, pingback terbuka 7.1.

Cara Memeriksa XML-RPC di Situs Anda

Sebelum menutup sesuatu, pastikan dulu ia memang terbuka. Ada empat cara mengecek yang bisa Anda lakukan sendiri, diurutkan dari yang paling mudah.

Buka alamatnya di browser. Ketik https://namasitus.com/xmlrpc.php di bilah alamat. Kalau muncul satu baris tulisan XML-RPC server accepts POST requests only. berarti berkas itu aktif dan siap menerima perintah. Kalau yang muncul halaman 403 atau 404, jalurnya sudah tertutup.

Baca kode status HTTP-nya. Cara ini lebih pasti karena tidak bergantung pada tampilan. Jalankan perintah curl berikut dari terminal:

Bash
curl -sSI https://namasitus.com/xmlrpc.php

Balasan 405 disertai header Allow: POST menandakan XML-RPC aktif. Angka 405 di sini bukan galat, melainkan cara server memberi tahu bahwa alamat itu ada tetapi hanya menerima metode POST.

Cari jejaknya di kode sumber halaman. WordPress mengumumkan keberadaan XML-RPC lewat sebuah tag di bagian head setiap halaman. Bentuknya <link rel="EditURI" type="application/rsd+xml"> dan nilainya menunjuk ke xmlrpc.php?rsd. Kalau tag itu masih ada, alat pihak ketiga akan menemukan pintu tersebut tanpa perlu menebak. Pada halaman pos tunggal yang pingback-nya masih terbuka, WordPress juga mengirim header X-Pingback berisi alamat xmlrpc.php. Header itu kerap tidak muncul karena banyak situs sudah menutup pingback atau layanan CDN-nya menyaring header tambahan.

Minta daftar perintahnya. Cek paling gamblang adalah memanggil system.listMethods, satu-satunya perintah yang mengembalikan seluruh daftar fungsi tanpa perlu login. Pada instalasi bawaan jawabannya memuat 79 nama, termasuk pingback.ping dan system.multicall. Kalau daftar itu keluar, semua fungsi di dalamnya bisa dipanggil siapa pun yang tahu alamatnya.

Empat Cara Menutup XML-RPC dan Bedanya

Langkah ini di kalangan pengguna WordPress lebih sering disebut disable XML-RPC. Keempat cara di bawah ini tidak setara, diurutkan dari yang paling longgar ke yang paling tegas, dan masing-masing menyisakan hal berbeda dalam keadaan terbuka.

Empat cara menutup XML-RPC dibandingkan: hanya blokir di web server yang menutup perintah berlogin sekaligus pingback.Empat cara menutup XML-RPC dibandingkan: hanya blokir di web server yang menutup perintah berlogin sekaligus pingback.

Langkah #1: Matikan Fungsi yang Butuh Login

Cara paling sering disarankan adalah menambahkan satu baris ke berkas functions.php tema turunan Anda atau ke plugin kecil buatan sendiri:

PHP
add_filter('xmlrpc_enabled', '__return_false');

Baris ini memang menghentikan seluruh 66 fungsi yang menuntut login, sehingga percobaan menebak kata sandi langsung ditolak. Namun ada hal yang perlu Anda ketahui, dan keterangan ini tertulis di dokumentasi dalam kode inti WordPress sendiri: filter tersebut tidak mematikan XML-RPC sepenuhnya. Fungsi yang tidak memerlukan login, termasuk pingback.ping, tetap melayani permintaan seperti biasa.

Pemeriksaan pada kode inti WordPress 7.1 memperkuat keterangan itu. Penanda hasil filter hanya dibaca di dua tempat, yaitu saat memproses login dan saat menyusun pesan galat. Fungsi yang menangani pingback tidak memeriksanya sama sekali.

Langkah #2: Buang Fungsi Pingback Secara Spesifik

Untuk menutup celah yang tersisa tanpa mematikan seluruh protokol, buang fungsi pingback dari daftar yang dilayani server. Cara ini cocok bagi Anda yang masih memakai Jetpack atau aplikasi ponsel:

PHP
add_filter('xmlrpc_methods', function ($m) {
    unset(
        $m['pingback.ping'],
        $m['pingback.extensions.getPingbacks']
    );
    return $m;
});

Setelah kode ini aktif, permintaan pingback dibalas galat "server error, requested method not found". Situs Anda tidak bisa lagi dijadikan penguat serangan, sementara fungsi penerbitan tetap berjalan. Langkah ini bisa digabungkan dengan pengaturan trackback dan pingback di halaman Diskusi, yang caranya dibahas terpisah di panduan menonaktifkan fitur trackback dan pingback.

Langkah #3: Blokir di Tingkat Web Server

Ini cara yang paling tegas, karena permintaan dihentikan sebelum PHP sempat dijalankan. Bebannya jauh lebih ringan bagi server dibanding dua cara sebelumnya. Untuk Apache, tambahkan blok berikut ke berkas .htaccess di akar situs:

APACHE
<Files "xmlrpc.php">
    Require all denied
</Files>

Untuk Nginx, tambahkan blok berikut ke dalam konfigurasi server situs Anda, lalu muat ulang layanannya:

Nginx
location = /xmlrpc.php {
    deny all;
}

Pengunjung yang mencoba membuka alamat itu akan menerima balasan 403. Perlu diketahui bahwa cara ini memutus semua pemakai XML-RPC tanpa kecuali, termasuk Jetpack dan aplikasi ponsel Anda sendiri. Sebagian penyedia layanan web hosting sudah menerapkan pemblokiran serupa di tingkat server, jadi ada baiknya Anda memeriksa dulu apakah langkah ini masih diperlukan.

Langkah #4: Pakai Plugin

Kalau Anda tidak ingin menyentuh berkas konfigurasi, tersedia plugin yang melakukan pekerjaan Langkah #1 dan #2 lewat antarmuka. Sebagian plugin keamanan menyeluruh juga sudah menyertakan sakelar XML-RPC di halaman pengaturannya. Kelemahannya, plugin bekerja setelah WordPress dimuat penuh, sehingga permintaan tetap membebani PHP dan basis data. Untuk situs yang diketuk ribuan kali sehari, Langkah #3 jauh lebih hemat.

Kelemahan dan Hal yang Perlu Anda Pertimbangkan

Menutup XML-RPC bukan keputusan tanpa konsekuensi. Ada tiga hal yang perlu Anda timbang sebelum memilih langkah paling tegas.

Beberapa layanan akan berhenti bekerja. Jetpack membutuhkan akses ke xmlrpc.php untuk membangun dan memelihara koneksinya. Aplikasi WordPress di ponsel juga memakai jalur ini untuk situs yang Anda kelola sendiri. Kalau keduanya Anda pakai, pemblokiran di tingkat web server akan langsung memutus sambungan.

Menutup satu pintu tidak menutup pintu lainnya. Sebuah pengukuran pada periode 16 sampai 29 Januari 2017 mencatat 108 juta serangan mengarah ke XML-RPC dan 106 juta ke wp-login.php — praktis berimbang. Yang lebih penting, 224.461 alamat IP menyerang keduanya sekaligus, sementara hanya 11.453 alamat yang khusus menyasar XML-RPC. Artinya sebagian besar penyerang akan pindah jalur begitu satu jalur ditutup.

Ada jalan tengah yang sering terlewat. Kalau Anda membutuhkan aplikasi ponsel tetapi khawatir pada penebakan kata sandi, buat Application Password dari halaman profil pengguna. Masukkan kata sandi itu ke aplikasi sebagai ganti kata sandi akun Anda. Penyerang yang menebak kata sandi akun Anda lewat XML-RPC akan selalu gagal, karena yang berlaku di jalur itu adalah rangkaian 24 karakter acak.

Rekomendasi konkretnya begini. Kalau situs Anda tidak memakai Jetpack dan Anda tidak pernah menerbitkan tulisan dari ponsel, pakai Langkah #3 dan tutup sepenuhnya. Kalau salah satu dari keduanya Anda pakai, gabungkan Langkah #2 dengan Application Password, dan biarkan sisanya terbuka. Untuk situs mana pun, aktifkan 2FA di halaman login, karena di sanalah setengah dari serangan sesungguhnya menumpuk.

Pertanyaan yang Sering Muncul Seputar XML-RPC

Apakah berkas xmlrpc.php boleh dihapus begitu saja?

Sebaiknya tidak. Berkas itu bagian dari inti WordPress, sehingga akan dikembalikan setiap kali Anda memperbarui versi. Menghapusnya juga membuat pemeriksaan integritas berkas melaporkan ketidakcocokan. Pilihan yang lebih rapi adalah memblokirnya lewat konfigurasi web server, karena berkasnya tetap utuh sementara aksesnya tertutup.

Kenapa membukanya di browser hanya menampilkan satu baris kalimat?

Karena XML-RPC hanya menerima permintaan POST, sedangkan browser mengirim GET saat Anda mengetik alamat. Server menjawabnya dengan kode 405 dan kalimat penjelasan. Baris itu justru pertanda berkas tersebut berfungsi normal, bukan tanda situs Anda bermasalah.

Apakah XML-RPC dan REST API bisa aktif bersamaan?

Bisa, dan pada instalasi bawaan keduanya memang aktif berdampingan. Keduanya jalur terpisah dengan alamat berbeda, yaitu /xmlrpc.php dan /wp-json/. Menutup salah satunya tidak mengganggu yang lain, sehingga editor blok tetap berjalan meski XML-RPC diblokir total.

Apakah XML-RPC hanya ada di WordPress?

Tidak. XML-RPC adalah protokol umum yang usianya lebih tua daripada WordPress. Ia dipakai di banyak tempat lain, mulai dari pustaka standar Python sampai penyelarasan konfigurasi pada perangkat firewall. WordPress hanya kebetulan menjadi pemakainya yang paling terlihat karena jumlah pemasangannya sangat besar.

Aplikasi WordPress di ponsel berhenti bekerja, apa jalan keluarnya?

Longgarkan pemblokiran dari Langkah #3 menjadi Langkah #2, lalu amankan sisi autentikasinya dengan Application Password. Kalau Anda memakai alamat IP tetap di rumah atau kantor, blok konfigurasi web server juga bisa disetel agar hanya mengizinkan alamat tersebut.

Kesimpulan

XML-RPC adalah protokol berumur lebih dari dua dekade yang masih menempel di WordPress demi menjaga kompatibilitas dengan alat lama. Sebagian risikonya sudah berkurang seiring perbaikan di inti WordPress, terutama sejak percobaan login berganda dalam satu permintaan tidak lagi membuahkan hasil. Namun fungsi pingback yang terbuka tanpa login tetap menjadikan situs Anda calon penguat serangan bagi orang lain.

Keputusannya bergantung pada apa yang benar-benar Anda pakai. Situs yang tidak menyentuh Jetpack maupun aplikasi ponsel sebaiknya menutup jalur ini di tingkat web server. Situs yang masih membutuhkannya cukup membuang fungsi pingback dan beralih ke Application Password. Yang perlu dihindari hanyalah membiarkan semuanya terbuka tanpa pernah memeriksanya.

Semoga artikel ini membantu.