Dalam Konteks Apa Plugin Bertanggung Jawab atas Validasi Data / Sanitasi?

17

Saya ingin memastikan semua data di plugin / tema saya ditangani dengan aman sebelum memasukkan basis data dan sebelum di-output ke browser. Masalah saya adalah ada beberapa situasi di mana API menangani sanitasi untuk Anda - seperti saat menyimpan kolom meta pos - dan lainnya di mana pembuat plugin / tema sepenuhnya bertanggung jawab untuk melakukannya - seperti saat menyimpan pengaturan khusus.

Untuk cakupan pertanyaan ini, saya tidak khawatir tentang memvalidasi data di tingkat domain - misalnya, memeriksa bahwa bidang Usia pada formulir adalah antara 0 dan 120, atau bahwa alamat email valid. Saya hanya khawatir tentang keamanan - misalnya, menghindari permintaan SQL untuk menghindari injeksi SQL saat menyimpan ke database, atau membersihkan data yang di-output ke template HTML untuk menghindari XSS.

Untuk sanitasi output, saya tahu bahwa Anda selalu perlu menggunakan fungsi seperti esc_html()dan esc_attr()ketika memasukkan variabel ke template HTML. Tapi, bagaimana dengan saat menggunakan tag templat ? Apakah mereka semua sudah membersihkan output? Jika ya, untuk konteks apa (HTML umum, atribut tag, dll)? Beberapa fungsi memiliki varian untuk konteks yang berbeda (seperti the_title_attribute(), tetapi sebagian besar tidak.

Untuk sanitasi input, saya tahu bahwa saya perlu menggunakan $wpdb->prepare()ketika membuat kueri manual, tetapi bagaimana dengan saat menggunakan API Pengaturan untuk membuat halaman pengaturan plugin, atau menyimpan kolom meta pos untuk jenis posting khusus?

Saat ini saya baru saja menggali melalui Core dan membaca tutorial setiap kali saya menggunakan fungsi untuk mencari tahu apakah itu membersihkan atau tidak, tapi itu rawan kesalahan dan memakan waktu. Saya berharap menemukan semacam daftar komprehensif dari semua situasi yang mungkin dan apakah API menanganinya atau tidak. misalnya,

API memvalidasi / membersihkan

  • Menyimpan meta pos dengan update_postmeta()
  • Menyimpan meta pengguna dengan update_user_meta()
  • Mengeluarkan judul posting - gunakan varian yang sesuai dengan konteks the_title()
  • dll

Anda harus memvalidasi / membersihkan secara manual

  • Menyimpan opsi plugin dengan API Pengaturan. Lewati panggilan balik sebagai parameter ke-3 dari register_setting().
  • Kueri basis data langsung: Bungkus kueri di $wpdb->prepare().
  • Mengeluarkan variabel dalam HTML. Gunakan esc_attr(), esc_html(), dll
  • dll

Saya juga tertarik untuk memahami mengapa API menyediakannya dalam situasi tertentu, tetapi tidak yang lain. Saya berasumsi itu ada hubungannya dengan sifat data yang tidak diketahui, tetapi akan senang mendengar penjelasan yang menyeluruh.

Ian Dunn
sumber
Saya suka pertanyaan ini. Saya memiliki pemikiran yang sama seperti Anda. Saya pikir jika ada daftar kapan kita harus memvalidasi / membersihkan secara manual, itu akan bagus. +1.
Anh Tran
1
@Rwis, tolong lihat jawaban saya. Anda harus selalu memvalidasi. Sanitasi lebih rumit, karena 'aman' tergantung pada konteks. Secara umum, jika menggunakan WordPress API dengan data yang diketahui WordPress ( the_title(), the_permalink()dll) Anda baik-baik saja tetapi dengan data khusus Anda tidak (misalnya get_post_meta()). Jika ragu, bersihkan diri Anda - tidak ada salahnya.
Stephen Harris
@StephenHarris: Saya membaca komentar Anda. Saya tahu itu juga. Tetapi saya memiliki pendapat yang sama dengan Ian Dunn. Saya pikir alasan utama dia bertanya adalah "lakukan cukup, tidak lebih, tidak kurang".
Anh Tran
1
Sebenarnya saya tidak keberatan berbuat salah di sisi kehati-hatian dan melakukan terlalu banyak validasi / sanitasi, tetapi saya pikir ada kasus di mana melarikan diri dua kali dapat menjadi masalah.
Ian Dunn

Jawaban:

15

Ada dua konsep di sini:

  • validasi - memastikan data valid , yaitu integer adalah integer, tanggal adalah tanggal (dalam format yang tepat, dll). Ini harus dilakukan sesaat sebelum menyimpan data.
  • Sanitasi - membuat tanggal aman untuk digunakan dalam konteks saat ini (mis. melarikan diri dari query SQL, atau keluar dari HTML pada output).

Validasi hampir secara universal hanya untuk Anda . Anda tahu data apa yang Anda minta dari pengguna, dan Anda tahu data apa yang Anda harapkan - WordPress tidak. Validasi akan dilakukan, misalnya, pada save_posthook sebelum menyimpannya ke database dengan update_post_meta, atau mungkin dilakukan dengan menentukan fungsi callback di Pengaturan API, yang disebut tepat sebelum WordPress menyimpan data.

Sanitasi sedikit lebih campuran. Ketika berhadapan dengan data yang diketahui secara asli oleh WordPress (mis. Ubin tulisan) Anda dapat yakin bahwa WordPress telah membuat data tersebut aman. Namun 'aman' tergantung pada konteks; apa yang aman untuk digunakan pada halaman, belum tentu aman sebagai atribut elemen. Oleh karena WordPress akan memiliki fungsi yang berbeda untuk konteks yang berbeda (misalnya the_title(), the_title_rss(), the_title_attribute()) - sehingga Anda perlu menggunakan yang benar .

Sebagian besar pengaya Anda mungkin berurusan dengan meta pos - atau mungkin data acara dari tabel khusus. WordPress tidak tahu untuk apa data ini atau untuk apa, jadi tentu saja tidak tahu cara membuatnya aman. Ini terserah kamu . Hal ini sangat penting dalam menggunakan esc_url(), esc_attr(), esc_textarea()dll untuk mencegah masukan berbahaya untuk dapat kode embed. Karena WordPress tahu next_posts()seharusnya mencetak url ke halaman, itu berlaku esc_url()- tetapi dengan meta pos, katakanlah, itu tidak tahu bahwa itu menyimpan url - atau apa yang ingin Anda lakukan dengannya (jika mencetak,esc_url() ,, jika mengarahkan ulang esc_url_raw(). Jika di dobut - berbuat salah di sisi hati-hati dan melarikan diri sendiri - dan lakukan ini selambat mungkin.

Akhirnya - bagaimana dengan menyimpan data? Apakah Anda perlu membuatnya aman? Seperti disebutkan Anda lakukan perlu memastikan data yang valid. Tetapi jika menggunakan WordPress API ( wp_insert_post(), update_post_meta()dll) maka Anda tidak perlu membersihkan data - karena ketika menyimpan data, satu-satunya sanitasi yang perlu Anda lakukan adalah keluar dari pernyataan SQL - dan WordPress melakukan ini. Jika Anda menjalankan pernyataan SQL langsung (katakan untuk membaca / menulis data dari tabel kustom) maka Anda harus menggunakan $wpdbkelas untuk membantu Anda membersihkan pertanyaan Anda.

Saya menulis posting blog ini tentang sanitisasi dan validasi data yang mungkin bermanfaat bagi Anda - di dalamnya saya berbicara tentang apa yang diharapkan dari Anda dalam hal ini.

Stephen Harris
sumber
Hai Stephan, terima kasih atas penjelasannya. Itu memang membantu saya memahaminya sedikit lebih baik, tetapi apa yang sebenarnya saya cari adalah semacam daftar lengkap, seperti contoh yang saya berikan. Sepertinya pendekatan Anda adalah membuat tebakan yang berpendidikan apakah WP menanganinya, atau berbuat salah di sisi hati-hati dan selalu membersihkan. Saya akan merasa lebih percaya diri tentang hal itu jika saya memiliki daftar yang berwibawa dan komprehensif, daripada mengandalkan pemahaman saya tentang hal itu. Saya juga khawatir bahwa melarikan diri ganda dapat menyebabkan masalah.
Ian Dunn
Saya juga baru saja memperbarui pertanyaan untuk mengklarifikasi beberapa hal.
Ian Dunn
0

Tidak yakin itu menyeluruh, tetapi dengan plugin atau tema apa pun, input pengguna harus disanitasi. Operasi basis data harus dilakukan dengan menggunakan metode $ wpdb->. Semua data $ _GET dan $ _POST harus disanitasi.

Ini adalah praktik terbaik untuk pemrograman PHP daripada WordPress.

Jadi, sebagai kesimpulan, jika ada fungsi WordPress, gunakan itu, jika tidak, bersihkan variabel Anda dan masukan sendiri.

Jika saya terlalu kabur, tanyakan pertanyaan yang lebih spesifik.

Ciprian
sumber
3
Saya mengerti bahwa itu selalu perlu disanitasi, tetapi pertanyaannya adalah tentang siapa yang melakukan sanitasi di setiap situasi tertentu. Terkadang WordPress melakukannya secara otomatis, dan terkadang Anda harus melakukannya secara manual. Saya telah memperbarui pertanyaan untuk mencoba dan membuatnya lebih jelas.
Ian Dunn
Bahkan ketika menggunakan update_user_meta (), Anda masih perlu memvalidasinya, karena nilai yang diperbarui mungkin berasal dari formulir yang terbuka atau dari input pengguna. Jika itu nilai yang berasal dari skrip, seperti keputusan orang dalam, dari loop if / else, maka Anda tidak harus membersihkannya.
Ciprian
1
Nilai yang Anda lewati update_user_meta()akan dilewati stripslashes_deep()dan sanitize_meta()masuk update_metadata(), lalu $wpdb->prepare()masuk $wpdb->update(). Jadi, saya pikir Anda tidak perlu membersihkannya. Apakah saya melewatkan sesuatu?
Ian Dunn