Безопасность
WordPress — самая распространённая система, и потому самая атакуемая. Большинство взломов происходит не через ядро, а через темы и плагины с небрежным кодом. Правил немного, но соблюдать их нужно всегда: очищать ввод, экранировать вывод, проверять токен и права.
Экранирование вывода
Любое значение перед выводом на страницу экранируют — функцией, подходящей к месту:
<?php
// card.php
?>
<h2><?php echo esc_html($title); ?></h2>
<a href="<?php echo esc_url($link); ?>" title="<?php echo esc_attr($hint); ?>">Открыть</a>
<div class="content"><?php echo wp_kses_post($html); ?></div>| Функция | Где применять |
|---|---|
esc_html() | Текст между тегами |
esc_attr() | Значение атрибута |
esc_url() | Адрес в href и src |
esc_js() | Строка внутри JavaScript |
wp_kses_post() | HTML, в котором допустимы только безопасные теги |
Экранируют как можно позже — прямо в строке вывода.
Очистка ввода
Данные от посетителя очищают до сохранения:
$name = sanitize_text_field($_POST['name'] ?? '');
$email = sanitize_email($_POST['email'] ?? '');
$age = absint($_POST['age'] ?? 0);
$slug = sanitize_title($_POST['slug'] ?? '');
$comment = sanitize_textarea_field($_POST['comment'] ?? '');
$page = esc_url_raw($_POST['website'] ?? '');sanitize_text_field() убирает теги, переносы строк и лишние пробелы.
Токены nonce
Токен подтверждает, что запрос отправлен со страницы вашего сайта, а не подстроен чужим. В форму его добавляет одна функция:
<?php
// form.php
?>
<form method="post">
<?php wp_nonce_field('mytheme_feedback', 'feedback_nonce'); ?>
<textarea name="message"></textarea>
<button type="submit">Отправить</button>
</form>При обработке токен проверяют:
// functions.php
add_action('init', function () {
if (!isset($_POST['feedback_nonce'])) {
return;
}
if (!wp_verify_nonce($_POST['feedback_nonce'], 'mytheme_feedback')) {
wp_die('Срок действия формы истёк. Обновите страницу.');
}
$message = sanitize_textarea_field($_POST['message'] ?? '');
// сохранить сообщение
});Для ссылок есть wp_nonce_url(), для страниц панели — check_admin_referer().
Проверка прав
Токен отвечает на вопрос «откуда запрос», права — «можно ли этому пользователю»:
if (!current_user_can('edit_post', $postId)) {
wp_die('Недостаточно прав.', 403);
}
if (!current_user_can('manage_options')) {
return;
}Проверяют право на действие, а не роль: роли на сайте могут быть изменены.
Запросы к базе
Значения в запросы SQL вставляют только через $wpdb->prepare() — об этом был прошлый урок.
Защита файлов
<?php
// includes/helpers.php
defined('ABSPATH') || exit;В wp-config.php рабочего сайта отключают редактор кода в панели и показ ошибок:
// wp-config.php
define('DISALLOW_FILE_EDIT', true);
define('WP_DEBUG', false);Что ещё важно
| Мера | Зачем |
|---|---|
| Обновлять ядро, темы и плагины | Большинство взломов использует давно исправленные уязвимости |
| Удалять неиспользуемые плагины | Отключённый плагин всё ещё может быть уязвим |
| HTTPS | Пароль и cookie не перехватить в сети |
| Резервные копии | Единственный способ восстановиться после взлома |
Частая ошибка
Очистка при сохранении не отменяет экранирование при выводе. Данные могли попасть в базу другим путём — через импорт, другой плагин, старую версию кода. Правило запоминается так: очищай на входе, экранируй на выходе — и то и другое всегда.