Типичные параметры $allowed для wp_kses
У меня есть пользовательское текстовое поле для поста, которое я хочу очистить с помощью wp_kses
перед обновлением метаданных поста.
Я искал примеры распространённых настроек $allowed
, но нашёл только такой пример:
$allowed = array(
'a' => array( // разрешаем только теги a
'href' => array() // и у этих якорей может быть только атрибут href
)
);
Какие типичные параметры $allowed
для wp_kses
? Может кто-то предоставить пример того, что обычно фильтруют?

Я не согласен с решением, предложенным @JaredCobb. Функция wp_kses()
гораздо более гибкая, чем представленный им метод. Она может удалять нежелательные атрибуты из тегов, не уничтожая сами теги. Например, если пользователь введёт <strong class='foo'>
, функция wp_kses()
вернёт <strong>
, если вы не разрешаете классы, тогда как strip_tags()
полностью удалит тег <strong>
.
@redconservatory: Атрибуты, которые вам нужно использовать, выглядят следующим образом:
$args = array(
//форматирование
'strong' => array(),
'em' => array(),
'b' => array(),
'i' => array(),
//ссылки
'a' => array(
'href' => array()
)
);
Это позволит использовать жирный и курсивный текст без атрибутов, а также теги ссылок с атрибутом href
... и ничего больше. Здесь используется принцип белого списка, о котором @jaredcobb справедливо заметил, что он более предпочтителен в данном случае.

Разве нельзя указать strip_tags, какие теги разрешены? http://php.net/manual/en/function.strip-tags.php

Хотя теперь, когда я вижу, как она удаляет нежелательные классы, я понимаю, что wp_kses лучше...

Возможно, я неясно объяснил... Но да, wp_kses
предоставляет больше контроля, чем нативные PHP-опции. Кажется, я это говорил. Я также использовал слово "атрибуты". Я имел в виду, что все зависит от вашего случая использования. Если кто-то пытается защитить свои данные от всех тегов, то, по моему мнению, лучше использовать strip_tags, но это скорее мое предпочтение, чем что-то еще. Удачи.

Я бы начал с того же массива $allowedtags
, который WordPress использует для комментариев. Этот массив можно найти в файле [директория wordpress]/wp-includes/kses.php
. Эти настройки кажутся мне разумными по умолчанию и хорошей отправной точкой. Вот их массив...
$allowedtags = array(
'a' => array(
'href' => true,
'title' => true,
),
'abbr' => array(
'title' => true,
),
'acronym' => array(
'title' => true,
),
'b' => array(),
'blockquote' => array(
'cite' => true,
),
'cite' => array(),
'code' => array(),
'del' => array(
'datetime' => true,
),
'em' => array(),
'i' => array(),
'q' => array(
'cite' => true,
),
'strike' => array(),
'strong' => array(),
);
Я НЕ рекомендую использовать PHP-функцию strip_tags
вместо wp_kses
.
Никогда не используйте strip_tags для фильтрации контента неизвестных пользователей!
Я записал короткое видео, объясняющее Почему wp_kses() в WordPress безопаснее, чем strip_tags() в PHP.

Вот так. Это работает как в WordPress, так и за его пределами.
<?php
$str = ' I am <strong>stronger</strong> and cooler every single day <aaaaa>. ';
echo orbisius_html_util::strip_tags($str);
/**
* Утилитарный класс для работы с HTML
* @author Svetoslav Marinov (SLAVI) | http://orbisius.com
*/
class orbisius_html_util {
/**
* Использует wp_kses из WordPress для удаления некоторых HTML-тегов, но разрешает определенные атрибуты
* использование: orbisius_html_util::strip_tags($str);
* использует wp_kses() из WordPress
* @param str $buffer строковый буфер
* @return str очищенный текст
*/
public static function strip_tags($buffer) {
static $default_attribs = array(
'id' => array(),
'class' => array(),
'title' => array(),
'style' => array(),
'data' => array(),
'data-mce-id' => array(),
'data-mce-style' => array(),
'data-mce-bogus' => array(),
);
$allowed_tags = array(
'div' => $default_attribs,
'span' => $default_attribs,
'p' => $default_attribs,
'a' => array_merge( $default_attribs, array(
'href' => array(),
'target' => array('_blank', '_top'),
) ),
'u' => $default_attribs,
'i' => $default_attribs,
'q' => $default_attribs,
'b' => $default_attribs,
'ul' => $default_attribs,
'ol' => $default_attribs,
'li' => $default_attribs,
'br' => $default_attribs,
'hr' => $default_attribs,
'strong' => $default_attribs,
'blockquote' => $default_attribs,
'del' => $default_attribs,
'strike' => $default_attribs,
'em' => $default_attribs,
'code' => $default_attribs,
);
if (function_exists('wp_kses')) { // WordPress доступен
$buffer = wp_kses($buffer, $allowed_tags);
} else {
$tags = array();
foreach (array_keys($allowed_tags) as $tag) {
$tags[] = "<$tag>";
}
$buffer = strip_tags($buffer, join('', $tags));
}
$buffer = trim($buffer);
return $buffer;
}
}

Здравствуйте, г-н Светослав, безопасно ли это использовать в наши дни? Я искал простой, но безопасный способ санитизации пользовательского ввода для моей админки (не WordPress). Мне нужно разрешить только базовое HTML-форматирование, такое как в вашем коде: <b>, <I>, <u>. Как вы думаете, можно ли использовать strip_tags($_POST['myDoc']) или нужно что-то еще для безопасности? Спасибо за помощь!

Привет, используй мой код. Он проверяет, выполняется ли в контексте WordPress - тогда использует функции WP, в противном случае возвращается к php strip_tags. Также лучше использовать $_REQUEST вместо $_POST, потому что в какой-то момент данные могут передаваться как GET-параметр.

спасибо за ответ :-). Сейчас столкнулся с проблемой... если вставить форматированный HTML или, например, код из Sublime Text 3, большая часть текста теряется, должно быть какое-то скрытое форматирование, которое ломает скрипт.

Возможно, я очищаю html, как указал в ответе выше, ищу \n, \r и т.д., но проблема все еще остается :-(. Очистка вставленных данных может быть огромной проблемой, несколько лет назад я использовал копирование в textedit для очистки скопированных строк, но я не могу ожидать, что мои пользователи будут делать то же самое.

Я использовал wp_kses
только тогда, когда мне нужно было явно разрешить/отфильтровать атрибуты HTML-тегов (например, я хочу разрешить тег <image>
с атрибутом src=""
, но не хочу, чтобы они могли добавлять href=""
, style=""
или что-либо ещё к тегу изображения). В этом случае wp_kses
оказывается полезным, потому что (как видно в вашем примере) можно очень точно настроить фильтрацию. Однако я редко использую wp_kses
, так как считаю, что несколько встроенных функций PHP (ниже) справляются с задачей и понятнее при просмотре кода спустя несколько месяцев.
Если вы хотите полностью удалить HTML-теги (за исключением, возможно, нескольких разрешённых), я всегда использую strip_tags
. Можно передать строку с разрешёнными тегами (например, <p> <br> <strong>
) или любые другие безвредные теги. Это даёт пользователю некоторый контроль над форматированием, если это подходит для вашего случая. Мне нравится strip_tags
, потому что он использует белый список для санитизации данных (то есть всё удаляется, кроме явно разрешённого).
Если ваша цель — разрешить пользователям вводить любой HTML, но вы хотите отображать их текст в исходном виде (например, примеры кода), используйте htmlspecialchars
. Это преобразует HTML-символы в их закодированные эквиваленты, что позволяет безопасно выводить их на страницу.
Вы можете встретить код, использующий str_replace
, который "ищет" плохие теги вроде или . Я не рекомендую такой подход, потому что он использует чёрный список для санитизации данных, и вам придётся постоянно следить за его актуальностью.
Подводя итог, всё зависит от того, для чего используются ваши метабоксы. Если вы защищаетесь от ввода пользователей (которые могут быть злоумышленниками), я рекомендую strip_tags
, разрешая только некоторые безвредные теги. Если у вас есть веская причина для детального управления тегами и атрибутами пользовательского контента, используйте wp_kses
.

Разве wp_kses()
не делает всё то же, что и strip_tags()
, и даже больше? Я за простоту, но также считаю, что есть аргумент против "неожиданностей". wp_kses()
— это "способ WordPress", и поскольку мы пишем код для WordPress, есть аргумент, что это, вероятно, лучший выбор. Более того, если в будущем мы захотим разрешить определённые комбинации тегов/атрибутов, использование wp_kses()
с самого начала не потребует рефакторинга.

Вы также можете использовать функцию wp_kses_post, которая применяется к содержимому записи и требует только данные в качестве параметра.
Подробнее здесь: http://codex.wordpress.org/Function_Reference/wp_kses_post

@Светослав Маринов
Я добавил этот код сразу после $buffer = trim($buffer);
$string_limpa = array(
'<div><p><\/div>' => '<br>',
'<div><br><\/div>'=> '<br>',
'<div align="left"><br><\/div>' => '<br>',
'<div align="center"><br><\/div>' => '<br>',
'<div align="right"><br><\/div>' => '<br>',
'<div style="text-align: left;"><br><\/div>' => '<br>',
'<div style="text-align: center;"><br><\/div>' => '<br>',
'<div style="text-align: right;"><br><\/div>' => '<br>',
'<div style="text-align: justify;"><br><\/div>' => '<br>',
'class="Apple-style-span"' => '<br>',
'<p><br></p>' => '<br>',
'<p><b></p>' => '<br>',
'<p><i></p>' => '<br>',
'<p><u></p>' => '<br>',
'\r' => '<br>',
'\n' => '<br>',
'\t' => ' ',
'\0' => ' ',
'\x0B' => '<br>',
'<p style="text-align: center;"><br></p>' => '<br>'
);
return strtr($buffer, $string_limpa);
чтобы попытаться очистить html и избежать скрытых символов, которые ломают код при вставке, но это не работает - html очищается, но скрытые символы остаются.
