- Вопрос или проблема
- Ответ или решение
- 1. Понимание Nonce
- 2. Предупреждения о валидации Nonce
- 3. Корректировка кода
- Скорректированный код для постраничной навигации (строка 95):
- 4. Корректировка кода для удаления выбранных элементов (строка 143):
- 5. Рекомендации по санитации
- 6. Альтернативный подход
- Заключение
Вопрос или проблема
Я пытаюсь программировать свой первый плагин для WordPress. Он работает довольно хорошо, но я получаю некоторые предупреждения при проверке моего плагина с помощью Plugin Check (PCP). Вот они:
Строка Столбец Тип Код Описание Редактировать ссылку
95 27 WARNING WordPress.Security.NonceVerification.Recommended Обработка данных формы без проверки nonce.
95 59 WARNING WordPress.Security.NonceVerification.Recommended Обработка данных формы без проверки nonce.
143 48 WARNING WordPress.Security.NonceVerification.Recommended Обработка данных формы без проверки nonce.
143 73 WARNING WordPress.Security.NonceVerification.Recommended Обработка данных формы без проверки nonce.
Соответствующий код в строке 95 выглядит следующим образом:
// Проверка nonce для пагинации
if (isset($_GET['paged']) && !empty($_GET['paged'])) {
if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'pagination_nonce')) {
echo '<p>Неверный запрос. Пожалуйста, попробуйте еще раз.</p>';
return;
}
}
Соответствующий код в строке 143 выглядит следующим образом:
// Проверка nonce для delete_selected
if (isset($_POST['delete_selected']) && isset($_POST['media_ids']) && is_array($_POST['media_ids'])) {
if (check_admin_referer('delete_unused_media', 'delete_unused_media_nonce')) {
delete_selected_media($_POST['media_ids']);
} else {
echo '<p>Неверный запрос. Пожалуйста, попробуйте еще раз.</p>';
}
}
Теперь я работал несколько дней над тем, что я мог бы изменить, чтобы предупреждения больше не появлялись, но у меня не получается. Может кто-нибудь помочь мне?
[Сравнение] У меня была та же проблема с похожим кодом, чтобы получить входное значение из $_REQUEST['plugin']
; так же, как ваш код, который хочет получить входное значение из $_GET['paged']
.
Этот код читает $_REQUEST['plugin']
один раз, а затем использует эту внутреннюю переменную в дальнейшем. Если она не существует, код будет работать с строковым значением ”; что совместимо с empty(), и т.д.
$request = isset($_REQUEST['plugin']) ? $_REQUEST['plugin'] : '';
Запуск ‘Plugin Check (PCP) 1.2.0’ выявил 3 предупреждения с этим единственным утверждением.
Начнем с WordPress.Security.NonceVerification.Recommended
.
Интересно, что все 3 предупреждения относятся к одной и той же строке и столбцу (то есть к одному и тому же утверждению).
[Расследование] Эксперименты с большим количеством кодовой смеси показали, что ‘столбец’ конкретно указывает на интересующее утверждение в предупреждении.
~столбец 45 для $_REQUEST['plugin']
в моем коде.
~столбец 27 для !empty($_GET['paged'])
в вашем коде.
[Решение] Устранение 2-го и 3-го предупреждений привело к исчезновению 1-го предупреждения. Больше никакого WordPress.Security.NonceVerification.Recommended
.
Конкретно добавив sanitize_text_field(wp_unslash( ))
к первому утверждению, которое пыталось использовать входное значение.
Мой оригинальный код:
$request = isset($_REQUEST['plugin']) ? $_REQUEST['plugin'] : '';
Мой новый код:
$request = isset($_REQUEST['plugin']) ? sanitize_text_field(wp_unslash($_REQUEST['plugin'])) : '';
Запуск ‘Plugin Check (PCP) 1.2.0’ теперь не имеет предупреждений; даже nonce
исчезло.
[Рекомендация] Не могли бы вы попробовать очистить входное значение перед его первым использованием. В данном случае оно используется как параметр для empty().
Ваш оригинальный код:
if (isset($_GET['paged']) && !empty($_GET['paged'])) {
Ваш новый код:
if (isset($_GET['paged']) && !empty(sanitize_text_field(wp_unslash($_GET['paged'])))) {
Тогда каждое использование входного значения также нужно будет очистить перед использованием в любых сравнениях или присваиваниях: $_GET['paged']
, $_GET['_wpnonce']
и $_POST['media_ids']
.
Будьте осторожны при выборе, какую функцию sanitize_
использовать для каждого входного значения. Ознакомьтесь с официальным списком функций очистки WordPress и проведите эксперименты, чтобы найти подходящую для каждого случая.
Возможно, вам не нужно будет ничего менять для $_POST['delete_selected']
, потому что оно используется только в isset()
; что, похоже, является устойчивым к предупреждениям (предположительно, потому что это не оператор сравнения или присваивания?).
Тогда запуск ‘Plugin Check (PCP) 1.2.0’ больше не должен показывать предупреждение о nonce
.
Ответ или решение
Сформулированный вами вопрос о валидации nonce в WordPress при разработке плагина ставит важную задачу безопасной обработки данных. Неправильная работа с данными может привести не только к предупреждениям, которые вы видите, но и к потенциальным уязвимостям в безопасности. Мы предлагаем детализированный подход к решению вашей проблемы.
1. Понимание Nonce
Nonce (номер используемый один раз) — это метод защиты, предоставляемый WordPress для предотвращения атак CSRF (Cross-Site Request Forgery). При помощи nonce можно удостовериться, что запрос инициирован пользователем, который имеет доступ к ресурсу.
2. Предупреждения о валидации Nonce
Предупреждения, которые вы получаете, указывают на то, что обработка данных формы происходит без проверки nonce. Это может быть опасно, так как злоумышленник может отправить вредоносный запрос к вашему плагину.
3. Корректировка кода
Для устранения предупреждений вы можете действовать в следующем направлении:
- Добавление валидации Nonce: Убедитесь, что в вашем коде действительно используется проверка для всех входящих данных, которые могут быть подвержены изменениям. Используйте функции
wp_verify_nonce()
иcheck_admin_referer()
для проверки значений nonce, связанных с действиями, такими как страница пагинации или удаление данных.
Скорректированный код для постраничной навигации (строка 95):
// Валидация nonce для пагинации
if (isset($_GET['paged']) && !empty($_GET['paged'])) {
if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'pagination_nonce')) {
echo '<p>Некорректный запрос. Пожалуйста, попробуйте еще раз.</p>';
return;
}
}
4. Корректировка кода для удаления выбранных элементов (строка 143):
// Валидация nonce для удаления выбранных элементов
if (isset($_POST['delete_selected']) && isset($_POST['media_ids']) && is_array($_POST['media_ids'])) {
if (check_admin_referer('delete_unused_media', 'delete_unused_media_nonce')) {
delete_selected_media(array_map('sanitize_text_field', $_POST['media_ids']));
} else {
echo '<p>Некорректный запрос. Пожалуйста, попробуйте еще раз.</p>';
}
}
5. Рекомендации по санитации
Как вы уже заметили, правильная санитация входных данных — это ключ к безопасности вашего плагина. Используйте соответствующие функции санитации, такие как sanitize_text_field()
, esc_url()
, esc_html()
, и другие, в зависимости от необходимого контекста.
6. Альтернативный подход
Вместо повторной проверки для каждого значения nonce, вы можете внедрить централизованное управление с использованием классов или функций в вашем плагине, что упростит управление данными и улучшит читаемость кода.
Заключение
Эти изменения сделают ваш плагин более безопасным и надежным, устраняют предупреждения и обеспечивают безопасность обработки данных. Используйте лучшие практики разработки, предусмотренные WordPress, и всегда тестируйте вводимые данные на наличие уязвимостей. Если вам потребуется дополнительная поддержка или есть вопросы, не стесняйтесь обращаться к сообществу разработчиков WordPress.