Зачем бежать, если the_content нет?

8

Встроенная функция the_contentпроходит через несколько фильтров, но не выходит из вывода. Это было бы трудно для этого, так как HTML и даже некоторые скрипты должны быть пропущены.

При выводе, the_content, кажется, проходит через эти фильтры (начиная с 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' );

Это также делает простую замену строки:

$content = str_replace( ']]>', ']]>', $content );

А затем get_the_content выполняет небольшую обработку, связанную со ссылкой «more» и ошибкой в ​​иностранных языках.

Ни один из них не препятствует внедрению сценария XSS, верно?

При сохранении данных в продезинфицировать через wp_kses_post. Но так как это дорогостоящий процесс, я понимаю, почему он не используется на выходе.

Практическое правило для выхода из WordPress заключается в том, что нужно избегать всего, независимо от входной санитарии, и как можно позже. Я прочитал несколько статей, в которых говорится об этом, потому что базу данных не следует считать надежным источником.

Но по вышеуказанным причинам the_content не следует этому. Кроме того, основные темы (например, TwentyNineteen) не добавляют дополнительного выхода при выводе.

Итак ... почему это помогает чему-либо сбежать в другом месте? Если бы я был хакером с доступом к базе данных, я бы просто добавил свой код к содержанию поста?

tmdesigned
источник
Вы забылиwp_kses_post
Том Дж. Новелл
Он запускается через wp_kses_post на выходе? Куда?
tmdesigned

Ответы:

10

Если бы я был хакером с доступом к базе данных, я бы просто добавил свой код к содержанию поста?

Если у вас есть доступ к базе данных, есть вероятность, что у вас достаточно доступа, что побег не остановит вас. Бегство не поможет вам, если вас взломали. Это не должно Есть и другие причины для побега. Два основных из них, о которых я могу думать:

Иметь дело с неанизированным вводом

Содержание WordPress очищается при сохранении, но не все остальное. Например, содержимое, переданное через строку запроса в URL, не подвергается санитарной обработке. Также не обязательно содержание в файлах перевода. Оба они являются источниками контента, который не имеет никакого отношения к скомпрометированному сайту. Поэтому переводимый текст и контент, извлеченные из URL, должны быть экранированы.

Чтобы пользователи случайно не сломали разметку

Побег не только для безопасности. Это также необходимо для предотвращения случайного нарушения пользователями разметки своего сайта. Например, если пользователь, помещающий кавычки или >символы в какой-либо контент в вашем плагине, нарушит разметку, вы должны избежать этого вывода. Вы не хотите быть чрезмерно агрессивными в санации при вводе, потому что есть совершенно веские причины, по которым пользователь может захотеть использовать эти символы.


«Бегство - это не только защита от плохих парней. Это просто делает наше программное обеспечение долговечным. Против случайного плохого ввода, против злонамеренного ввода или против плохой погоды ».

Это из руководства WordPress VIP по побегу . По этому вопросу можно сказать гораздо больше, и вы должны прочитать его.

Джейкоб Питти
источник
Спасибо, это полезно. Я читал пост на VIP о побеге, и автор особо упомянул идею, что кто-то получил доступ к БД, но не к серверу. Однако я думаю, что ваши рассуждения на этот счет имеют больше смысла. И, я полагаю, иногда вы избегаете уязвимого контента из базы данных, даже если кто-то не имеет полного доступа к базе данных, то есть с помощью плагина или даже просто комментария.
tmdesigned
9

Я на самом деле инженер в VIP, который много пересматривает код :) Я отмечаю пропущенные побеги.

но не выходит из вывода

Не совсем, это не уходит на выходе, что удивительно для большинства людей. Это потому, что если вы супер администратор, у вас есть такая unfiltered_htmlвозможность, поэтому она не может выйти на выходе. Вместо этого он запускает его wp_kses_postна входе. В идеале вы бы удалили эту возможность, хотя.

Вот реализация в настоящее время:

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;
}

С the_contentдругой стороны, идеальный механизм для избежания всего, что проходит через фильтр:

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

Таким образом, мы делаем содержимое безопасным, а затем пропускаем его через фильтр, избегая удаления вложений и т. Д.

Так зачем убегать

Смысл экранирования состоит в том, чтобы генерировать действительный HTML, а дополнительная безопасность, которую он обеспечивает, является просто приятным побочным эффектом.

Чтобы пользователи случайно не сломали разметку

Есть много причин, чтобы убежать, но в основном вы оправдываете ожидания. Возьмите следующий код:

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

Мы ожидаем, $urlчто URL будет подходящим для hrefатрибута, но что, если это не так? Хорошо, почему это оставлено на волю случая, давайте обеспечим это:

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

Теперь это всегда будет URL. Не имеет значения, вставит ли изображение хакер $url, или пользователь введет неправильное поле, или существует вредоносный скрипт. Это всегда будет действительный URL, потому что мы сказали, что это будет URL. Конечно, это может быть очень странный URL, но он всегда будет соответствовать ожиданиям, что URL будет там. Это очень удобно, будь то для проверки разметки, безопасности и т. Д.

Сказав, что побег не является проверкой, побег не санитария. Это отдельные шаги, которые происходят в разные моменты жизненного цикла. Побег заставляет вещи соответствовать ожиданиям, даже если это мешает им сделать это.

Иногда мне нравится думать о том, чтобы сбежать как одно из тех японских игровых шоу с гигантской пенопластовой стеной с вырезом. Участники должны соответствовать форме собаки, или они выбрасываются, только для наших целей есть лазеры и ножи вокруг отверстия. Все, что осталось в конце, будет в форме собаки, и это будет неумолимым и строгим, если вы еще не в форме собаки.

Помните:

  • санировать рано
  • подтвердить рано
  • бежать поздно
  • часто убегать

Безопасность - это многоэтапный, многоуровневый метод защиты, выход - один из внешних уровней защиты на выходе. Он может искажать код атаки на скомпрометированном сайте, делая его бесполезным, мешать открывать эксплойты и следить за тем, чтобы ваш клиент не нарушал сайт, помещая теги в поля, которые они не должны. Это не замена для других вещей, и это, безусловно, самый недоиспользуемый инструмент безопасности в руководстве для разработчиков.

Что касается того, почему бежать, если the_contentнет? Если у вас есть наводнение и 5 дыр в стене, но только для того, чтобы исправить 3, вы пожимаете плечами и ничего не исправляете? Или вы уменьшаете риск и уменьшаете зону атаки?

Возможно, я могу помочь исправить эти последние 2 отверстия с помощью этого фрагмента:

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

Здесь мы устанавливаем приоритет на максимально возможное число в PHP, затем добавляем 1, чтобы оно переполнялось до минимально возможного числа, которое может быть представлено. Таким образом, все вызовы the_contentбудут избегать значения до любых других фильтров. Этот способ встраивания и т. Д. Все еще работает, но пользователи не могут проникнуть в опасный HTML через базу данных. Кроме того, обратите внимание на удаление unfiltered_htmlвозможности из всех ролей

Том Дж Новелл
источник
1
Спасибо за дополнительную перспективу. Я действительно прочитал ваш пост на эту тему на вашем сайте, и мне было интересно, есть ли у вас что-нибудь добавить.
tmdesigned
4

Смысл экранирования состоит в том, чтобы генерировать действительный HTML, а дополнительная безопасность, которую он обеспечивает, является просто приятным побочным эффектом.

Фильтры, применяемые к контенту, генерируют действительный HTML из чего-то, что представляет собой смесь HTML и некоторого другого текста, который имеет некоторый другой синтаксис, такой как шорткоды. Тот факт, что часть содержимого уже является действительным HTML, не позволяет применять экранирование для всего этого.

Что касается ksesсвязанных функций, вы не можете применять их в основном потому, что у вас недостаточно контекста, чтобы знать, какой из них использовать. Например, может быть какой-то процесс, который использует the_contentфильтр для добавления JS к содержимому публикации, поскольку ядро ​​не может догадаться, основываясь на таких вещах, как автор сообщения, является ли JS допустимым или нет.

Итак ... почему это помогает чему-либо сбежать в другом месте? Если бы я был хакером с доступом к базе данных, я бы просто добавил свой код к содержанию поста?

Опять же, экранирование предназначено для генерации правильного HTML. С точки зрения безопасности, это не то, что экранирование обеспечивает безопасность, а то, что код, который удаляется, должен быть подозрительным, поскольку его легче использовать. Например, то, как ядро ​​использует _eи «__» для переводов, означает, что любой, кто сможет убедить вас установить неофициальный перевод, может добавить сложный способ обнаружения JS в файле перевода и взломать ваш сайт. Это хороший пример того, «делай, что я говорю, а не то, что я делаю».

Марк Каплун
источник
Спасибо, Марк, за дополнительную перспективу.
tmdesigned
2

Если бы я был хакером с доступом к базе данных, я бы просто добавил свой код к содержанию поста?

Я думаю, что ваш вопрос отвечает сам. Если вы были хакером с доступом к БД, то вы уже получили доступ, который вам требуется. Экранирование вывода не меняет этого вообще.

Причиной экранирования вывода является оценка ненадежных данных, чтобы хакер не получил такой доступ в первую очередь.

butlerblog
источник
Спасибо за Ваш ответ. Я думаю, что я слишком сосредоточился на идее предотвращения хакера, который я скучал по лесу за деревьями.
tmdesigned