Mengapa melarikan diri jika is_content tidak?

8

Fungsi the_contentbawaan 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?

tm dirancang
sumber
Anda lupawp_kses_post
Tom J Nowell
Ini berjalan melalui wp_kses_post pada output? Dimana?
tmdesigned

Jawaban:

10

Jika saya seorang hacker dengan akses ke database, bukankah saya hanya menambahkan kode saya ke konten posting?

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.


“Lolos bukan hanya tentang melindungi dari orang jahat. Itu hanya membuat perangkat lunak kami tahan lama. Terhadap input buruk acak, terhadap input jahat, atau terhadap cuaca buruk. "

Itu dari panduan VIP WordPress untuk melarikan diri . Ada banyak hal untuk dikatakan tentang masalah ini, dan Anda harus membacanya.

Jacob Peattie
sumber
Terima kasih, itu sangat membantu. Saya telah membaca sebuah posting di VIP tentang melarikan diri dan penulis secara khusus menyebutkan gagasan seseorang telah mendapatkan akses ke DB tetapi tidak ke server. Namun saya pikir alasan Anda tentang hal itu lebih masuk akal. Dan, saya kira, kadang-kadang Anda melarikan diri konten rentan dari database bahkan tanpa seseorang yang telah memiliki lengkap akses ke database, yaitu melalui plugin atau bahkan hanya komentar.
tmdesigned
9

Saya sebenarnya seorang insinyur di VIP yang melakukan banyak review kode :) Saya menandai banyak yang hilang.

tetapi tidak luput output

Tidak cukup, itu tidak luput pada output, yang mengejutkan bagi kebanyakan orang. Ini karena jika Anda seorang admin super Anda memiliki unfiltered_htmlkemampuan, sehingga tidak dapat lepas pada output. Sebaliknya itu dijalankan melalui wp_kses_postinput. Idealnya Anda akan menghapus kemampuan itu.

Berikut adalah implementasinya saat ini:

function the_content( $more_link_text = null, $strip_teaser = false ) {
    $content = get_the_content( $more_link_text, $strip_teaser );

    /**
     * Filters the post content.
     *
     * @since 0.71
     *
     * @param string $content Content of the current post.
     */
    $content = apply_filters( 'the_content', $content );
    $content = str_replace( ']]>', ']]>', $content );
    echo $content;
}

Mekanisme ideal untuk lolos dari segala sesuatu yang melewati the_contentfilter adalah:

echo apply_filters( 'the_content', wp_kses_post( $content ) );

Dengan cara ini kami membuat konten aman, kemudian menjalankannya melalui filter, menghindari embed dll dilucuti.

Jadi Kenapa Kabur

Inti dari melarikan diri adalah untuk menghasilkan HTML yang valid, keamanan tambahan yang diberikannya hanya efek samping yang bagus.

Untuk mencegah pengguna secara tidak sengaja merusak markup

Ada banyak alasan untuk melarikan diri, tetapi pada dasarnya, Anda menegakkan harapan. Ambil kode berikut:

<a href="<?=$url?>">

Kami berharap $urlberisi URL yang cocok untuk hrefatribut, tetapi bagaimana jika bukan? Nah mengapa biarkan saja, mari kita menegakkannya:

<a href="<?=esc_url( $url )?>">

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, dll

Karena 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:

  • membersihkan awal
  • validasi lebih awal
  • melarikan diri terlambat
  • sering melarikan diri

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_contenttidak? 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:

add_filter( 'the_content' function( $content ) {
    return wp_kses_post( $content );
}, PHP_INT_MAX + 1 );

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_contentakan 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 hapus unfiltered_htmlkemampuan dari semua peran

Tom J Nowell
sumber
1
Terima kasih atas perspektif tambahan. Saya sebenarnya telah membaca posting Anda tentang subjek ini di situs Anda dan bertanya-tanya apakah Anda akan menambahkan sesuatu.
tmdesigned
4

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 ksesfungsi 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 menggunakan the_contentfilter untuk menambahkan JS ke konten posting sehingga inti tidak dapat menebak berdasarkan hal-hal seperti penulis posting apakah JS tersebut sah atau tidak.

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?

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 _edan '__` 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".

Mark Kaplun
sumber
Terima kasih, Mark, untuk perspektif tambahan.
tmdesigned
2

Jika saya seorang hacker dengan akses ke database, bukankah saya hanya menambahkan kode saya ke konten posting?

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.

butlerblog
sumber
Terima kasih atas jawaban anda. Saya pikir saya menjadi terlalu fokus pada ide untuk mencegah seorang hacker sehingga saya merindukan hutan untuk pepohonan.
tmdesigned