Каковы лучшие практики при экранировании the_title()?

Вопрос или проблема

У меня есть кастомная тема. Я хочу вывести заголовок моего поста. Я уже достиг этого, используя <h1><?php the_title();?></h1>. Однако некоторые говорят, что это не экранировано. Действительно, я могу запустить JS, например <script>alert("test");</script>, если помещу это в заголовок поста. Я пробовал (1) <?php esc_html(the_title('<h1>','</h1>'))?> , но это также запускает вышеупомянутый JS и не выводит никакой HTML. Также пробовал (2) <h1><?php echo esc_html(the_title);</h1> с тем же результатом, что и (1).

С Новым Годом! /dfr

Вы использовали бы это так:

<?php the_title(); ?>

Действительно, я могу запустить JS, например alert(“test”), если помещу это в заголовок поста.

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

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

Так что вместо этого:

  • Используйте the_title() как есть, чтобы напрямую вывести заголовок
  • Или, если вы обеспокоены тем, что у пользователя есть возможность unfiltered_html, используйте echo esc_html( get_the_title(

Однако обратите внимание, что заголовок используется во многих других местах, таких как OEmbed и SEO теги, а также теги заголовка, и может быть легче удалить возможность unfiltered_html, и я рекомендую вам сделать это, хотя бы в качестве меры безопасности.

Я пробовал (1) <?php esc_html(the_title('<h1>','</h1>'))?>

Это не сработало по нескольким причинам, которые не имеют отношения к WordPress, но подчеркивают отсутствующие знания о базах PHP

  1. Нет echo! Поэтому даже если бы это сработало, оно бы ничего не напечатало
  2. the_title по умолчанию не возвращает значение, оно выводит напрямую

Это означает, что код эквивалентен этому:

echo esc_html('');
the_title('<h1>','</h1>');

Также пробовал (2) <h1><?php echo esc_html(the_title);</h1> с тем же результатом

Это лучше, так как включает echo, но вы попросили экранировать саму функцию, а не заголовок поста, это почти эквивалентно этому:

echo esc_html( function the_title() { .... } );

Что, вероятно, приведет к предупреждению PHP типа:

Warning: Uncaught Error: Object of class Closure could not be converted to string in...

Важные моменты, которые следует учесть на будущее:

  • Сначала проверьте, но общее правило заключается в том, что the_... будет выводить напрямую без echo, а get_the или get_ требуют оператора echo и функции экранирования.
  • Функции, начинающиеся с the_, как правило, выполняют собственное экранирование внутри
  • Не делайте двойное экранирование! esc_html( esc_html( это очень плохо и может позволить вещам пройти, если они правильно сконструированы
  • вызов функции включает () где-то, вы не можете применить экранирование как модификатор или буфер, вызывая escape(function_name)
  • экранируйте как можно позже, желательно в момент вывода
  • избегайте сбора HTML-фрагментов в переменную, а затем вывода их в конце, это делает очень трудным правильное экранирование вещей
  • не экранируйте ввод, для этого предназначены очистка и валидация, экранирование предназначено только для вывода
  • Не пытайтесь использовать esc_js и esc_sql, они не делают то, что, кажется, делают, и имеют очень специфические внутренние применения. wpdb->prepare должен покрыть всю SQL-связанную экранирование, а wp_json_encode может подготавливать данные для JavaScript, так что вам не нужно конструировать их из строк при показе страницы

Ответ или решение

Выбор оптимальной практики для экранирования функции the_title() в WordPress имеет важное значение для обеспечения безопасности и корректности отображения заголовков на вашем сайте. Давайте разберем детали этого процесса с учетом того, как работает the_title(), и возможных ошибок, которые вы можете столкнуться при его использовании.

Проблема и контекст

Вы используете пользовательскую тему и выводите заголовок поста с помощью кода <h1><?php the_title(); ?></h1>. Однако, как вы заметили, это не экранированный вывод, и если у пользователя есть привилегия unfiltered_html, это может привести к выполнению небезопасного кода, такого как <script>alert("test");</script>.

Почему ваше текущее решение не работает

  1. Ошибка в экранировании:

    • Вы использовали esc_html(the_title('&lt;h1&gt;','&lt;/h1&gt;')), что неверно, так как the_title() по умолчанию выводит данные напрямую и не возвращает значение. В данном случае вы экранировали пустую строку.
  2. Отсутствие вывода:

    • В версии <h1><?php echo esc_html(the_title);</h1> функция the_title была передана как объект, что приводит к PHP ошибке, когда система пытается экранировать саму функцию, а не её вывод.

Правильное решение

Чтобы корректно экранировать заголовок поста и избежать потенциальных проблем безопасности, следуйте этому подходу:

<h1><?php echo esc_html( get_the_title() ); ?></h1>
  1. Используйте get_the_title():

    • Эта функция возвращает строку, которая является заголовком поста, без непосредственного вывода её на экране.
  2. Экранирование с помощью esc_html():

    • Примените esc_html() к строке, полученной от get_the_title(), чтобы обеспечить безопасный вывод, экранировав все HTML теги и возможный опасный код.

Рекомендации по безопасности и производительности

  • Избегайте привилегий unfiltered_html:

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

    • Всегда старайтесь экранировать данные непосредственно перед их выводом. Это позволит предотвратить внедрение вредоносного кода в HTML.
  • Понимание WordPress функций:

    • Функции, начинающиеся с get_, как правило, возвращают значение, которое вы должны выводить вручную, в то время как the_ обычно выводят данные сразу.

Заключение

Чтобы обеспечить безопасность вашего сайта, всегда экранируйте пользовательский ввод на этапе вывода с помощью esc_html() и правильно выбирайте подходящие функции WordPress (the_title() vs. get_the_title()). Это создаст более безопасную среду для вашего сайта и улучшит качество кода.

Оцените материал
Добавить комментарий

Капча загружается...