В этой статье я расскажу, как обезопасить себя от инъекций нежелательного кода через переводы в WordPress

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

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

Проблема

Чтобы разобраться в ситуации, давайте вспомним ответ на вопрос — «Как чаще всего мы вставляем перевод в нашу тему или плагин?»

<?php
echo '<p>' . __('Sometext', 'mytheme') . '</p>';


Казалось бы, что может пойти не так? Давайте подумаем.
Достаточно вставить в файл перевода закрывающуюся скобку ">" или <script>alert('hello');</script> и всё… верстка поехала, сайт выдал ошибку. А всё могло быть даже хуже.

Решение

У WordPress есть две замечательные функции, которые позволяют избежать вставки нежелательных символов в текст перевода:

codex.wordpress.org/Function_Reference/esc_html_2
codex.wordpress.org/Function_Reference/esc_html_e

esc_html__ и esc_html_e соответственно.

Отличие лишь в том, что esc_html_e не нужно выводить через «echo».

Во всех местах, где вы используете конструкцию
__('something', 'mytheme')

нужно использовать
esc_html__('something', 'mytheme')


А конструкцию
_e('something', 'mytheme')

заменить на
esc_html_e('something', 'mytheme')


Ещё один момент

Если у нас имеется конструкция с атрибутом вида:

<?php
echo '<a href="#" title="' . __('Attribute value', 'mytheme') . '</a>';


То «эскейпить» её нужно функцией esc_attr__()

codex.wordpress.org/Function_Reference/esc_attr_2

Вывод

Правило «Не доверяй никому!» должно быть в основе разработки, и каждый даже самый минимальный момент ввода-вывода данных должен быть учтен при разработке, чтобы избежать печальных последствий. И переводы — не исключение.

И в завершение — Github для чтения

По данной ссылке кратко описана проблема вывода переводов без эскейпов:

github.com/Automattic/_s/issues/231

Комментарии (3)


  1. Core2Duo
    16.09.2015 19:15

    Поздравляю, вы открыли преобразование специальных символов HTML в их сущности.
    Функция esc_html__ всего лишь обертка. По сути, все сводится только к функции _wp_specialchars, которая, внезапно, является оберткой с некоторыми улучшениями над стандартной функцией htmlspecialchars.
    А вообще, воевать с переводчиками — странная затея. С тем же успехом можно воевать с разработчиками или собственными админами. Переводчик — это всё же команда сайта. Более того, текст перевода вполне может содержать HTML. Например, жирный текст, курсив, неразрывные пробелы и так далее. Вы же все это превратите в нечто нечитабельное.


    1. robots
      18.09.2015 12:32

      в переводах HTML тэгов быть не может.


  1. michael_vostrikov
    16.09.2015 19:37

    Непроверенные данные надо экранировать, прям открытие. В статье можно было хотя бы указать, чем отличаются функции esc_html__ и esc_attr__. Впрочем, выше уже все сказали.

    (а именно, ничем)
    // wp-includes/l10n.php
    
    function esc_html__( $text, $domain = 'default' ) {
    	return esc_html( translate( $text, $domain ) );
    }
    
    function esc_attr__( $text, $domain = 'default' ) {
    	return esc_attr( translate( $text, $domain ) );
    }
    
    
    // wp-includes/formatting.php
    
    function esc_html( $text ) {
    	$safe_text = wp_check_invalid_utf8( $text );
    	$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
    	return apply_filters( 'esc_html', $safe_text, $text );
    }
    
    function esc_attr( $text ) {
    	$safe_text = wp_check_invalid_utf8( $text );
    	$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
    	return apply_filters( 'attribute_escape', $safe_text, $text );
    }