Fungsi the_content
bawaan berjalan melalui beberapa filter, tetapi tidak luput dari keluaran. Akan sulit baginya untuk melakukannya, karena HTML dan bahkan beberapa skrip harus diizinkan masuk.
Saat mengeluarkan, the_content tampaknya dijalankan melalui filter ini (mulai 5.0):
add_filter( 'the_content', 'do_blocks', 9 );
add_filter( 'the_content', 'wptexturize' );
add_filter( 'the_content', 'convert_smilies', 20 );
add_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'shortcode_unautop' );
add_filter( 'the_content', 'prepend_attachment' );
add_filter( 'the_content', 'wp_make_content_images_responsive' );
(and)
add_filter( 'the_content', 'capital_P_dangit' );
add_filter( 'the_content', 'do_shortcode' );
Ia juga mengganti string sederhana:
$content = str_replace( ']]>', ']]>', $content );
Dan kemudian get_the_content melakukan sedikit pemrosesan terkait dengan tautan "lebih" dan bug dengan bahasa asing.
Tidak ada yang mencegah injeksi skrip XSS, bukan?
Ketika menyimpan, data yang dibersihkan melalui wp_kses_post. Tetapi karena ini adalah proses yang mahal, saya mengerti mengapa ini tidak digunakan pada output.
Aturan praktis untuk WordPress yang melarikan diri adalah bahwa segala sesuatu harus diloloskan, terlepas dari sanitasi input, dan selambat-lambatnya. Saya telah membaca beberapa artikel yang mengatakan ini, karena basis data tidak dapat dianggap sebagai sumber tepercaya.
Tetapi karena alasan di atas, konten__konten tidak mengikuti itu. Tema inti (TwentyNineteen) juga tidak menambahkan pelarian tambahan pada output.
Jadi ... mengapa itu membantu apa pun untuk melarikan diri di tempat lain? Jika saya seorang hacker dengan akses ke database, bukankah saya hanya menambahkan kode saya ke konten posting?
wp_kses_post
Jawaban:
Jika Anda memiliki akses ke database, kemungkinan Anda memiliki cukup akses sehingga melarikan diri tidak akan menghentikan Anda. Melarikan diri tidak akan membantu Anda jika Anda diretas. Itu tidak seharusnya. Ada alasan lain untuk melarikan diri. Dua hal utama yang dapat saya pikirkan adalah:
Untuk menangani input yang tidak bersih
Konten posting WordPress dibersihkan ketika disimpan, tetapi tidak semua yang lainnya. Konten yang diteruskan melalui string kueri di URL tidak dibersihkan, misalnya. Konten dalam file terjemahan juga tidak perlu. Keduanya adalah sumber konten yang tidak ada hubungannya dengan situs yang dikompromikan. Jadi teks dan konten yang dapat diterjemahkan yang ditarik dari URL harus diloloskan.
Untuk mencegah pengguna secara tidak sengaja merusak markup
Melarikan diri bukan hanya untuk keamanan. Anda juga memerlukannya untuk mencegah pengguna secara tidak sengaja merusak markup situs mereka. Misalnya, jika pengguna yang menempatkan tanda kutip atau
>
simbol dalam beberapa konten di plugin Anda akan merusak markup, maka Anda harus keluar dari output itu. Anda tidak ingin menjadi terlalu agresif dalam membersihkan input, karena ada alasan yang sangat masuk akal bagi pengguna untuk menggunakan karakter tersebut.Itu dari panduan VIP WordPress untuk melarikan diri . Ada banyak hal untuk dikatakan tentang masalah ini, dan Anda harus membacanya.
sumber
Saya sebenarnya seorang insinyur di VIP yang melakukan banyak review kode :) Saya menandai banyak yang hilang.
Tidak cukup, itu tidak luput pada output, yang mengejutkan bagi kebanyakan orang. Ini karena jika Anda seorang admin super Anda memiliki
unfiltered_html
kemampuan, sehingga tidak dapat lepas pada output. Sebaliknya itu dijalankan melaluiwp_kses_post
input. Idealnya Anda akan menghapus kemampuan itu.Berikut adalah implementasinya saat ini:
Mekanisme ideal untuk lolos dari segala sesuatu yang melewati
the_content
filter adalah:Dengan cara ini kami membuat konten aman, kemudian menjalankannya melalui filter, menghindari embed dll dilucuti.
Jadi Kenapa Kabur
Ada banyak alasan untuk melarikan diri, tetapi pada dasarnya, Anda menegakkan harapan. Ambil kode berikut:
Kami berharap
$url
berisi URL yang cocok untukhref
atribut, tetapi bagaimana jika bukan? Nah mengapa biarkan saja, mari kita menegakkannya:Sekarang akan selalu menjadi URL. Tidak masalah jika seorang hacker memasukkan gambar
$url
, atau jika pengguna mengetik di bidang yang salah, atau ada skrip berbahaya. Itu akan selalu menjadi URL yang valid karena kami mengatakan itu akan menjadi URL. Tentu itu mungkin URL yang sangat aneh, tetapi akan selalu memenuhi harapan bahwa URL akan ada di sana. Ini sangat berguna, baik untuk validasi markup, untuk keamanan, dllKarena itu, melarikan diri bukanlah validasi, melarikan diri bukanlah sanitasi. Itu adalah langkah terpisah yang terjadi pada titik yang berbeda dalam siklus hidup. Lolos memaksa hal-hal untuk memenuhi harapan, bahkan jika itu membuat mereka melakukannya.
Kadang-kadang saya suka berpikir untuk melarikan diri sebagai salah satu gameshow Jepang dengan dinding busa raksasa dengan potongan. Kontestan harus sesuai dengan bentuk anjing atau mereka dibuang, hanya untuk keperluan kita ada laser dan pisau di sekitar lubang. Apa pun yang tersisa pada akhirnya akan berbentuk anjing, dan itu akan menjadi tidak memaafkan dan ketat jika Anda belum berbentuk anjing.
Ingat:
Keamanan adalah langkah ganda, pertahanan berlapis-lapis, pertahanan adalah salah satu lapisan luar pertahanan pada keluaran. Itu dapat memotong kode serangan pada situs yang disusupi sehingga tidak berguna, menggagalkan eksploit terbuka, dan memastikan klien Anda tidak merusak situs dengan meletakkan tag di bidang yang tidak seharusnya. Ini bukan pengganti untuk hal-hal lain, dan sejauh ini merupakan alat keamanan yang paling tidak digunakan dalam buku pegangan pengembang.
Adapun mengapa harus melarikan diri jika
the_content
tidak? Jika Anda memiliki banjir, dan 5 lubang di dinding, tetapi hanya waktu untuk memperbaiki 3, apakah Anda mengangkat bahu dan tidak memperbaiki? Atau apakah Anda mengurangi risiko dan mengurangi area serangan?Mungkin saya dapat membantu memperbaiki 2 lubang terakhir dengan potongan ini:
Di sini kita menetapkan prioritas ke angka tertinggi di PHP, lalu tambahkan 1 sehingga meluap ke angka serendah mungkin yang dapat direpresentasikan. Dengan cara ini semua panggilan ke
the_content
akan luput dari nilai sebelum filter lainnya. Cara ini menanamkan dll masih berfungsi, tetapi pengguna tidak dapat menyelinap dalam HTML berbahaya melalui database. Selain itu, coba hapusunfiltered_html
kemampuan dari semua peransumber
Inti dari melarikan diri adalah untuk menghasilkan HTML yang valid, keamanan tambahan yang diberikannya hanya efek samping yang bagus.
Filter diterapkan pada konten, menghasilkan HTML yang valid dari sesuatu yang merupakan campuran dari HTML dan beberapa teks lain yang memiliki beberapa sintaksis lain seperti shortcode. Fakta bahwa beberapa konten sudah HTML yang valid mencegah aplikasi melarikan diri dari semua itu.
Sedangkan untuk
kses
fungsi terkait, Anda tidak dapat menerapkannya terutama karena Anda tidak memiliki konteks yang cukup untuk mengetahui mana yang akan digunakan. Misalnya, mungkin ada beberapa proses yang menggunakanthe_content
filter untuk menambahkan JS ke konten posting sehingga inti tidak dapat menebak berdasarkan hal-hal seperti penulis posting apakah JS tersebut sah atau tidak.Sekali lagi, melarikan diri adalah untuk menghasilkan HTML yang valid. Dari POV keamanan, bukan berarti melarikan diri menyediakan keamanan tetapi bahwa kode yang melarikan diri harus mencurigakan karena mungkin lebih mudah untuk dieksploitasi. Misalnya, cara inti menggunakan
_e
dan '__` untuk terjemahan berarti bahwa siapa pun yang dapat meyakinkan Anda untuk menginstal terjemahan non-resmi mungkin dapat menambah sulit untuk mendeteksi JS dalam file terjemahan dan meretas situs Anda. Ini adalah contoh yang baik dari "lakukan apa yang saya katakan dan bukan apa yang saya lakukan".sumber
Saya pikir pertanyaan Anda menjawab sendiri. Jika Anda seorang hacker dengan akses ke db, maka Anda sudah mendapatkan akses yang Anda butuhkan. Melarikan diri dari keluaran tidak mengubah itu sama sekali.
Alasan untuk menghindari output adalah mengevaluasi data yang tidak dipercaya untuk menghindari peretas mendapatkan akses itu sejak awal.
sumber