@ssnepenthe 's aswer adalah benar dalam mengatakan bahwa hook Anda gunakan bukan orang yang tepat sesuatu dalam permintaan yang masuk.
Informasi permintaan tersedia segera ke PHP, jadi Anda bisa menggunakan pengait paling awal yang tersedia untuk memeriksanya. Dan jika Anda ingin melakukan ini dalam konteks API permintaan, Anda harus menggunakan hook paling awal dari permintaan REST API. 'rest_pre_dispatch'
disarankan oleh @ssnepenthe baik-baik saja, mungkin opsi lain rest_authentication_errors
yang memungkinkan Anda untuk mengembalikan kesalahan jika ada sesuatu yang salah.
Tetapi Jack Johansson benar dalam mengatakan bahwa header HTTP (seperti header referer yang digunakan dalam aswer @ ssnepenthe) tidak dapat dipercaya, karena mereka sangat mudah diubah oleh klien. Jadi itu akan seperti menempatkan seorang penjaga keamanan di depan pintu yang hanya bertanya "apakah aman untuk membiarkan Anda masuk?" untuk siapa saja yang ingin masuk: itu tidak akan berhasil.
Tetapi soluisi yang diajukan jawaban Jack Johansson (nonce) juga bukan solusi nyata: seluruh titik nonces adalah berubah seiring waktu, dan titik akhir API publik tidak dapat memiliki hal-hal yang berubah berdasarkan waktu. Selain itu, WP nonces hanya dapat dipercaya ketika ada pengguna yang masuk, yang mungkin tidak berlaku untuk API publik dan jika pengguna masuk, mungkin tidak ada alasan untuk memeriksa domain yang masuk: Anda mempercayai pengguna, bukan mesin pengguna.
Jadi, apa yang harus dilakukan?
Ya, meskipun header HTTP tidak dapat dipercaya, tidak semua informasi yang tersedia $_SERVER
berasal dari header.
Biasanya, semua $_SERVER
nilai yang kunci-kuncinya dimulai yang dimulai dengan HTTP_
berasal dari header dan harus diperlakukan sebagai input pengguna yang tidak aman .
Tetapi, misalnya, $_SERVER['REMOTE_ADDR']
berisi alamat IP yang digunakan untuk koneksi TCP ke server Anda, yang berarti itu dapat dipercaya 1 .
Yang juga berarti, bahwa:
- mengkonfigurasi server dengan benar untuk menghasilkan
$_SERVER['REMOTE_HOST']
nilai (misalnya di Apache Anda perlu HostnameLookups On
di dalam Anda httpd.conf
) nilai itu
- gunakan
gethostbyaddr
untuk melakukan pencarian DNS terbalik untuk menyelesaikan nama domain dari IP yang disimpan di$_SERVER['REMOTE_ADDR']
Anda dapat memperoleh nama host yang cukup andal yang dapat Anda gunakan untuk mengecek daftar putih (untuk kode, Anda dapat mengadaptasi kode dari aswer @ ssnepenthe di mana Anda akan menggantinya $referer = $request->get_header('referer')
dengan $referer = gethostbyaddr($_SERVER['REMOTE_ADDR'])
).
Tapi ada masalah .
Jika server web Anda berada di belakang proksi terbalik (solusi yang cukup umum, sebenarnya) koneksi TCP ke server sebenarnya dibuat oleh proksi tersebut, maka itu $_SERVER['REMOTE_ADDR']
akan menjadi IP dari proksi tersebut, dan bukan IP dari klien yang awalnya mengirim permintaan.
IP permintaan asli dalam kasus seperti itu biasanya tersedia sebagai $_SERVER['HTTP_X_FORWARDED_FOR']
, tetapi menjadi salah satu dari $_SERVER
nilai - nilai yang dimulai dengan HTTP_
itu tidak benar-benar dapat dipercaya.
Jadi, jika server web Anda berada di belakang proxy terbalik 2 bahkan $_SERVER['REMOTE_ADDR']
tidak akan berguna untuk penjaga tersebut dan daftar putih berbasis domain hanya bisa diimplementasikan di tingkat proxy.
Singkatnya, solusi yang dapat diandalkan untuk pengamanan titik akhir API harus diimplementasikan dengan menggunakan beberapa mekanisme otentikasi nyata (misalnya oAuth) atau harus dilakukan dengan bertindak langsung pada konfigurasi server dan tidak pada tingkat aplikasi.
Catatan
1 Ya, secara teori itu bisa rusak jika seseorang meretas ISP Anda atau jika penyerang bertindak dari dalam LAN Anda, dalam kedua kasus sangat sedikit yang bisa Anda lakukan untuk aman.
2 Jika Anda tidak tahu apakah Anda berada di belakang proxy terbalik, Anda dapat mengirim permintaan dari PC lokal Anda dan memeriksa apakah $_SERVER['REMOTE_ADDR']
di server cocok dengan IP PC lokal dan juga jika $_SERVER['HTTP_X_FORWARDED_FOR']
ada dan cocok dengan IP PC lokal.