С точки зрения безопасности, следует ли избегать bloginfo () или get_bloginfo ()?

10

Я просмотрел много информации о безопасности тем и плагинов WP и понял, что вы должны избегать атрибутов и значений HTML в темах и плагинах. Я видел bloginfo()и echo get_bloginfo()использовал как стандартные, так и внутри esc_html()или esc_attr()функции.

Genesis и _s , базовая тема Automattic оба избегают этих значений, но собственное руководство по стандартам темы кодекса WP не говорит ничего о экранировании этих значений. Я посмотрел на код WP (wp-includes/option.php), и кажется, что есть небольшая очистка передаваемых значений,get_option()но также похоже, что есть фильтр, который плагин может перезаписывать для определенных значений.

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

Пол Грэм
источник

Ответы:

15

Мы должны посмотреть здесь немного глубже, чтобы получить ответ на ваш вопрос.

Итак, bloginfoэто простая обертка вокруг get_bloginfo.

<?php
function bloginfo( $show='' ) {
    echo get_bloginfo( $show, 'display' );
}

Обратите внимание на второй аргумент display. Давайте посмотрим, что это делает.

<?php
function get_bloginfo( $show = '', $filter = 'raw' ) {

    // snip snip, $output is fetched somewhere in here

    if ( 'display' == $filter ) {
        if ( $url )
            $output = apply_filters('bloginfo_url', $output, $show);
        else
            $output = apply_filters('bloginfo', $output, $show);
    }

    return $output;
}

Если фильтр установлен displayна выход, get_bloginfoон запускается через фильтр.

Вместо того, чтобы жестко кодировать что-то вроде вызова esc_htmlфункции, WP использует свою собственную систему ловушек, чтобы делать что-то. Место, где можно найти это, находится в wp-includes/default-filters.php. Быстрый поиск bloginfoв этом файле показывает ...

<?php
// Format strings for display.
foreach ( array( 'comment_author', 'term_name', 'link_name', 'link_description', 'link_notes', 'bloginfo', 'wp_title', 'widget_title' ) as $filter ) {
    add_filter( $filter, 'wptexturize'   );
    add_filter( $filter, 'convert_chars' );
    add_filter( $filter, 'esc_html'      );
}

bloginfoскрыт в foreachмассиве. Как вы можете видеть, вывод bloginfoполучает с esc_html.

Другими словами, это:

<?php
bloginfo('name');

Это эквивалентно этому:

<?php
echo esc_html(get_bloginfo('name'));

Или это:

<?php
echo get_bloginfo('name', 'display');

Таким образом, нет, выход bloginfoне должен быть экранирован. Также не выводится до get_bloginfoтех пор, пока второй аргумент установлен в display.

Однако предостережение заключается в том, что любой может удалить esc_htmlфильтр из bloginfo. Так что, скорее всего, безопаснее избежать выхода. И, конечно же, если вы используете выходные данные bloginfoдля чего-либо, кроме отображения HTML (например, в атрибуте alt изображения), вы должны выполнить его esc_attr.

chrisguitarguy
источник
Возможно, стоит проверить версию, в которой было введено использование фильтра. Возможно, это _s и генезис, которые были опубликованы в более старой версии, которая не включала этот код.
Марк Каплун
2
esc_htmlсуществует с 2.8, так что он подключен к bloginfo github.com/WordPress/WordPress/blob/2.8-branch/wp-includes/…
chrisguitarguy
Отличный ответ, спасибо. Я только сейчас разбираюсь в WP и, хотя мне было ясно, что bloginfo является оберткой get_bloginfo, не было ясно, что вывод обрабатывается. Я пропустил фильтры. Возможно, мне следует больше узнать о том, как WP обрабатывает код, который входит и покидает базу данных. У меня остался такой же взгляд, как когда я начинал, но, по крайней мере, теперь я знаю почему :)
Пол Грэм,