В WordPress nonces — это специальные уникальные токены, которые используются для защиты данных, передаваемых через формы, AJAX-запросы и другие операции, от атак типа CSRF (Cross-Site Request Forgery). В этой статье мы подробно разберём, как правильно создавать, проверять и использовать nonces, чтобы повысить безопасность вашего сайта на WordPress.
Что такое Nonce в WordPress и зачем они нужны
Nonces (Number used once) — это уникальные строки, которые создаются для подтверждения, что действие инициировано именно вашим сайтом и доверенным пользователем, а не злоумышленником. В WordPress nonce не является одноразовым числом в классическом понимании, а имеет ограниченный срок жизни (обычно 24 часа), что достаточно для большинства задач.
Использование nonce помогает защитить формы и запросы от подделки, предотвращая отправку вредоносных данных извне. Это особенно важно при работе с формами, изменяющими настройки, публикующими записи или выполняющими критичные операции.
Без nonce злоумышленник может отправить запрос от имени пользователя, что приведёт к нежелательным последствиям, например, удалению данных или изменению настроек.
Как создать nonce в WordPress: функции wpbegin_nonce_create и wpbegin_nonce_field
Для генерации nonce в WordPress используется функция wp_create_nonce. Мы создадим обёртку для неё с префиксом домена wpbegin для примера:
function wpbegin_nonce_create($action = -1) {
return wp_create_nonce($action);
}Параметр $action — это строка, которая помогает идентифицировать действие, к которому относится nonce, например, 'save_post' или 'delete_comment'. Это повышает безопасность, так как nonce будет работать только для заданного действия.
Чтобы добавить nonce в HTML-форму, удобно использовать функцию wp_nonce_field, которая автоматически создаёт скрытое поле с nonce и поле с action:
function wpbegin_nonce_field($action = -1, $name = '_wpnonce') {
wp_nonce_field($action, $name);
}Пример использования в форме:
<form method="post" action="">
<?php wpbegin_nonce_field('wpbegin_save_data'); ?>
<input type="text" name="my_input" />
<input type="submit" value="Сохранить" />
</form>Проверка nonce на сервере: wpbegin_verify_nonce
После отправки формы необходимо проверить nonce, чтобы убедиться, что запрос пришёл от вашего сайта и пользователя с нужными правами.
Для этого используется функция wp_verify_nonce, которую мы также обернём:
function wpbegin_verify_nonce($nonce, $action = -1) {
return wp_verify_nonce($nonce, $action);
}Пример проверки nonce при обработке формы:
if (isset($_POST['_wpnonce']) && wpbegin_verify_nonce($_POST['_wpnonce'], 'wpbegin_save_data')) {
// Обработка данных формы
} else {
// Ошибка: неверный nonce
wp_die('Ошибка безопасности: неверный запрос.');
}Использование nonce в AJAX-запросах WordPress
Nonces особенно важны при работе с AJAX, чтобы убедиться, что запросы выполняются только с вашего сайта и авторизованными пользователями.
Для создания nonce для AJAX можно использовать ту же функцию wp_create_nonce с уникальным action, например, 'wpbegin_ajax_action'. Затем nonce передаётся в JavaScript и добавляется к AJAX-запросу.
Пример создания nonce в PHP и передача его в скрипт:
function wpbegin_enqueue_scripts() {
wp_enqueue_script('wpbegin-script', get_template_directory_uri() . '/js/wpbegin.js', array('jquery'), null, true);
wp_localize_script('wpbegin-script', 'wpbegin_ajax_obj', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wpbegin_nonce_create('wpbegin_ajax_action')
));
}
add_action('wp_enqueue_scripts', 'wpbegin_enqueue_scripts');В JavaScript:
jQuery(document).ready(function($) {
$('#my-button').on('click', function() {
$.post(wpbegin_ajax_obj.ajax_url, {
action: 'wpbegin_my_action',
_wpnonce: wpbegin_ajax_obj.nonce,
data: 'some data'
}, function(response) {
console.log(response);
});
});
});В PHP для обработки AJAX-запроса обязательно проверяем nonce:
function wpbegin_handle_ajax() {
if (!isset($_POST['_wpnonce']) || !wpbegin_verify_nonce($_POST['_wpnonce'], 'wpbegin_ajax_action')) {
wp_send_json_error('Неверный nonce');
wp_die();
}
// Обработка данных
wp_send_json_success('Данные успешно обработаны');
wp_die();
}
add_action('wp_ajax_wpbegin_my_action', 'wpbegin_handle_ajax');Лучшие практики работы с Nonces в WordPress
Чтобы использовать nonces максимально эффективно и безопасно, придерживайтесь следующих рекомендаций:
- Всегда указывайте уникальный и понятный action при создании nonce. Это поможет избежать конфликтов и повысит безопасность.
- Используйте nonce везде, где происходит изменение данных, выполнение критичных действий или отправка форм.
- Проверяйте nonce обязательно перед обработкой данных. Если nonce невалиден, прекращайте выполнение и выводите ошибку.
- Для AJAX-запросов передавайте nonce вместе с данными, проверяйте их на сервере.
- Не используйте nonce для действий, не связанных с изменением данных (например, просто для отображения информации).
Пример создания и проверки nonce с пользовательскими функциями в плагине
Объединим всё в небольшой пример для плагина:
class WPBegin_Nonce_Example {
public function __construct() {
add_action('admin_menu', array($this, 'add_admin_page'));
add_action('admin_post_wpbegin_save_settings', array($this, 'handle_form'));
}
public function add_admin_page() {
add_menu_page('Настройки WPBegin', 'WPBegin', 'manage_options', 'wpbegin-settings', array($this, 'render_settings_page'));
}
public function render_settings_page() {
?>
<form method="post" action="admin-post.php">
<?php wp_nonce_field('wpbegin_save_settings'); ?>
<input type="hidden" name="action" value="wpbegin_save_settings" />
<label>Настройка:</label>
<input type="text" name="wpbegin_option" value="" />
<input type="submit" value="Сохранить" />
</form>
<?php
}
public function handle_form() {
if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'wpbegin_save_settings')) {
wp_die('Ошибка безопасности: неверный запрос.');
}
if (!current_user_can('manage_options')) {
wp_die('Нет прав для этого действия.');
}
update_option('wpbegin_option', sanitize_text_field($_POST['wpbegin_option']));
wp_redirect(admin_url('admin.php?page=wpbegin-settings&updated=true'));
exit;
}
}
new WPBegin_Nonce_Example();В этом примере создана страница настроек в админке с формой, защищённой nonce. При отправке происходит проверка nonce и прав пользователя. Если всё верно — данные сохраняются.
Заключение по теме Nonces в WordPress
Nonces — это простой и мощный инструмент для повышения безопасности вашего сайта на WordPress. Правильное использование nonce позволяет защититься от множества распространённых атак и гарантировать, что данные на сайте изменяются только доверенными пользователями и с вашего интерфейса.
Внедряйте nonces во все формы и AJAX-запросы, где происходит изменение данных, и вы значительно повысите безопасность своего проекта и доверие пользователей.