wp_verify_nonce vs check_admin_referer - разница и когда использовать
В чем разница, какую из них следует использовать?
Я знаю, что wp_verify_nonce проверяет временное ограничение, а check_admin_referer, как я понимаю, вызывает wp_verify_nonce, а также проверяет наличие админского URL-сегмента, но я немного запутался, какую из них и когда следует использовать.
Спасибо за разъяснения.
Я думал, что функция check_admin_referer проверяет nonce (она действительно вызывает wp_verify_nonce), а также URL источника запроса. Однако, изучив исходный код ядра, я понял, что это не так. Подумав, что это баг, я сообщил об этом, и Райан Борен ответил следующее:
На самом деле, если nonce действителен, источник запроса не проверяется. Ненадёжность источников запросов — одна из причин, по которой используются nonce. Nonce полностью заменяют проверку источника запроса. Единственный случай, когда мы проверяем источник, — это обработка условия обратной совместимости -1. -1 означает, что кто-то не использует nonce, поэтому мы возвращаемся к проверке источника запроса. Такое использование сейчас встречается очень редко. Название функции
check_admin_referer()сейчас неудачное, так как она почти никогда не проверяет источник запроса. Лучше было бы назвать её как-то вродеcheck_nonce(), но мы оставляем её как есть для обратной совместимости и в память о старых временах.
Таким образом, фактически разницы нет.
На самом деле есть одно важное различие, влияющее на использование... check_admin_referer завершает весь скрипт с помощью die(), если nonce недействителен, тогда как wp_verify_nonce возвращает false. Поэтому если есть обычные ситуации, когда nonce может быть невалидным, используйте wp_verify_nonce, чтобы остальная часть скрипта продолжала выполняться.
SeventhSteel
НЕТ! БУДЬТЕ ВНИМАТЕЛЬНЫ!!!
Не полагайтесь на check_admin_referer() без корректных параметров! Потому что в некоторых случаях она может не вызвать die() (вопреки вашим ожиданиям), а просто вернуть ответ false.
Посмотрите на логику поведения в исходном коде:
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
$result = isset( $_REQUEST[ $query_arg ] ) ? wp_verify_nonce( $_REQUEST[ $query_arg ], $action ) : false;
//Теперь проверка на "die()"
if ( ! $result && ( -1 !== $action || strpos( wp_get_referer(), admin_url() ) !== 0 ) ) {
die();
}
return $result;
}
Итак, вам нужно понять, как работает эта логика. Вот разбор:
A) Если вы вызываете просто check_admin_referrer() без параметров:
- ПОМНИТЕ, она будет использовать автоматически встроенное значение
_wpnonce(это безопасно, но всё равно убедитесь, что это поле присутствует при отправке). - Поскольку вы вызвали её без параметров, она использует значение по умолчанию
-1для действия, что приводит к пропуску проверкиdie(), и функция не завершится сdie() - Поэтому, при вызове без параметров всегда используйте:
if ( check_admin_referer() ) exit;
B) Если вы хотите, чтобы check_admin_referrer завершалась автоматически, тогда всегда создавайте свои nonce и вызывайте её с параметрами:
check_admin_referrer($action_name, $name_field );