В WordPress для защиты форм и запросов от CSRF (Cross-Site Request Forgery) используется механизм nonces — одноразовые токены, которые подтверждают, что действие выполняется именно авторизованным пользователем с вашего сайта. В этой статье мы подробно рассмотрим, как правильно создавать, проверять и использовать nonces в различных сценариях с примерами кода.
Что такое nonce в WordPress и зачем он нужен
Nonce (number used once) — это уникальная строка, которая генерируется для проверки подлинности запроса. В WordPress nonce не является криптографически сильным токеном, но достаточно надежен для предотвращения простых CSRF атак.
Основная задача nonce — удостовериться, что запрос, который выполняет изменение данных или важное действие, исходит от пользователя, который имеет на это право. Это защищает сайт от случайных или вредоносных переходов по ссылкам, отправки форм с других сайтов.
Без использования nonce злоумышленник может заставить пользователя выполнить нежелательное действие, например изменить настройки, удалить запись и т.п. Nonce проверяет, что запрос пришел с вашего сайта и был инициирован пользователем.
Генерация nonce: функции wp_create_nonce и wp_nonce_field
В WordPress существует несколько функций для работы с nonce:
wp_create_nonce($action)— генерирует nonce для конкретного действия;wp_nonce_field($action, $name, $referer, $echo)— добавляет скрытое поле с nonce в форму;wp_nonce_url($url, $action, $name)— добавляет nonce в URL.
Параметр $action — это строка, описывающая действие, например "wptests_delete_post_123". Она нужна для связки nonce с конкретным действием.
Пример создания nonce в форме
Представим, что нам нужно создать простую форму для удаления записи с ID 123.
<form method="post" action="">
<?php wp_nonce_field('wptests_delete_post_123', 'wptests_nonce'); ?>
<input type="hidden" name="post_id" value="123" />
<input type="submit" value="Удалить запись" />
</form>
Функция wp_nonce_field добавит два скрытых поля: с nonce и с реферером для дополнительной защиты.
Проверка nonce: функции wp_verify_nonce и check_admin_referer
После отправки формы нужно проверить nonce, чтобы убедиться, что запрос легитимен.
wp_verify_nonce($nonce, $action) возвращает 1 или 2, если nonce действителен, иначе false.
check_admin_referer($action, $name) проверяет nonce и реферер, при ошибке завершает выполнение скрипта с сообщением.
Пример обработки формы с проверкой nonce
function wptests_handle_delete_post() {
if ( ! empty( $_POST['wptests_nonce'] ) && ! empty( $_POST['post_id'] ) ) {
$nonce = sanitize_text_field( $_POST['wptests_nonce'] );
$post_id = intval( $_POST['post_id'] );
if ( wp_verify_nonce( $nonce, 'wptests_delete_post_' . $post_id ) ) {
// Безопасно удаляем запись
wp_delete_post( $post_id, true );
echo 'Запись удалена';
} else {
echo 'Ошибка проверки безопасности. Действие отменено.';
}
}
}
add_action( 'admin_post_wptests_delete_post', 'wptests_handle_delete_post' );
Здесь мы вручную проверяем nonce и только после этого удаляем запись.
Использование nonce в AJAX запросах WordPress
Для AJAX-запросов nonce также необходим для защиты. Как правило, nonce передается вместе с запросом и проверяется на сервере.
Пример добавления nonce в AJAX
В PHP генерируем nonce и передаем его в JS:
function wptests_enqueue_scripts() {
wp_enqueue_script( 'wptests-ajax', get_template_directory_uri() . '/js/wptests-ajax.js', array('jquery'), null, true );
wp_localize_script( 'wptests-ajax', 'wptests_ajax_obj', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'wptests_ajax_nonce' )
) );
}
add_action( 'wp_enqueue_scripts', 'wptests_enqueue_scripts' );
В JS отправляем запрос с nonce:
jQuery(document).ready(function($) {
$('#my-button').on('click', function() {
$.post(wptests_ajax_obj.ajax_url, {
action: 'wptests_my_action',
security: wptests_ajax_obj.nonce,
data: 'some data'
}, function(response) {
alert('Ответ сервера: ' + response);
});
});
});
На сервере проверяем nonce и обрабатываем запрос:
function wptests_handle_ajax() {
check_ajax_referer( 'wptests_ajax_nonce', 'security' );
$data = sanitize_text_field( $_POST['data'] );
// Логика обработки
wp_send_json_success( 'Данные получены: ' . $data );
}
add_action( 'wp_ajax_wptests_my_action', 'wptests_handle_ajax' );
add_action( 'wp_ajax_nopriv_wptests_my_action', 'wptests_handle_ajax' );
Практические советы по использованию nonce в WordPress
- Всегда связывайте nonce с конкретным действием, используя уникальную строку в параметре
$action. Это предотвращает повторное использование nonce для других целей. - Nonce имеет срок жизни 12–24 часа, поэтому не стоит использовать их для долгосрочного хранения данных.
- Для форм используйте
wp_nonce_field, для URL —wp_nonce_url. Это упрощает добавление nonce и предотвращает ошибки. - Всегда проверяйте nonce на сервере перед выполнением действия!
- Для AJAX-запросов используйте
check_ajax_referer— она сразу проверяет nonce и при ошибке завершает запрос.
Интеграция с плагинами WPShop для безопасности и удобства
Если вы используете плагины из WPShop, например, Clearfy Pro, он включает расширенные функции безопасности, которые автоматически работают с nonce и защищают от CSRF, упрощая вашу задачу.
Также в таких плагинах могут быть готовые AJAX-модели, в которых nonce уже реализованы, что позволяет быстро и безопасно внедрять интерактивные элементы без рисков.
Выводы и рекомендации
Использование nonce — обязательный элемент безопасности при работе с формами, ссылками и AJAX в WordPress. Освоив их правильное применение, вы защитите сайт от множества уязвимостей, связанных с подделкой запросов.
Не стоит пренебрегать проверками nonce даже в простых функциях — это поможет избежать неприятных ошибок и взломов.
Если вы хотите автоматизировать и расширить защиту, обратите внимание на специализированные плагины, которые интегрируются с nonce и добавляют дополнительные уровни безопасности.