Использование одноразовых чисел (nonces) для защиты WordPress
Одноразовые числа (nonces) – один из лучших способов защитить пользователей от возможных угроз. Они используются для защиты различных пользовательских действий, связанных с плагинами, таких как отправка форм, удаление записи и т.д., что обычно затрагивает базу данных.
В этой статье я опишу проблемы, которые могут исправить одноразовые данные, а также покажу, как использовать их для того, чтобы сделать продукты более защищенными.
Почему вам могут понадобиться nonces
Допустим, вы пишете плагин, который позволяет пользователям удалять пост из фронтэнда. Если говорить кратко, механизм удаления записей – это ссылка, которая переводит вас по адресу http://mysite.com/2015/02/12/my-article/?delete=true. Другими словами, ссылка на статью с прикрепленной строкой запроса.
Код, который вы реализуете на данной странице, проверяет, является ли пользователь администратором, и если да, то запись удаляется, а пользователь перенаправляется обратно к главной странице.
Вроде бы все безопасно, верно? В конце концов, вы ведь действительно проверили, является ли пользователь администратором!
Увы, но этого недостаточно. Есть две вещи, которые вы должны проверить перед тем, как каждое действие будет выполнено: права доступа и цель.
Вы проверили, что у пользователя имеются права доступа, но вы не можете быть уверены в том, что пользователь действительно хотел удалить запись.
Представьте, что я отправил вам электронное письмо, в котором написал, что нашел опечатку в одной из записей, и привел ссылку на нее. Если я создам ссылку в электронном письме, вы не сможете распознать цель, вы просто увидите кликабельный текст. Таким образом, если я добавлю к ней строку ?delete=true в самый конец, вы просто удалите запись, перейдя по ссылке.
Справиться с этим помогают случайные числа (nonces). Nonce – это специальный код, который генерируется на момент действия. Если вы используете nonce, ссылка может иметь следующий вид: http://mysite.com/2015/02/12/my-article/?delete=true&_wpnonce=234283223. А поскольку одноразовые данные будут всегда разные, я не смогу отправить вам простую ссылку, поскольку процесс удаления не будет работать без корректных nonce.
Что же такое nonce?
Nonce – это сокращение от «number used once», используются они в криптографии для защиты данных.
В WordPress nonce реализованы несколько иначе, поскольку они не являются числами, а также не используются однократно, однако их цель и их использование во многом похоже. WordPress использует хэш, и nonces могут использоваться более одного раза, у них есть короткое время истечения.
Использование Nonces в WordPress
Процесс состоит из двух шагов: вы генерируете nonce перед выполнением действия (помещая одноразовые числа в ссылку или в виде скрытого поля формы) и проверяете его в целевом назначении. Вам понадобятся некоторые функции для этого.
Добавление nonce к формам
Чтобы добавить nonce к форме, вы должны будете включить скрытое поле с именем и значением. WordPress позволяет это сделать с помощью функции wp_nonce_field().
Вы можете использовать ее с одним параметром (в своем самом простом виде):
wp_nonce_field( 'delete-post-' . get_the_ID() );
Функция создаст для вас два поля, одно из которых будет для nonce, а другое – для реферера, которого WordPress может тоже проверять.
<input type="hidden" id="_wpnonce" name="_wpnonce" value="37b392c8a0" /> <input type="hidden" name="_wp_http_referer" value="/2015/02/13/my-article/" />
Функция фактически дает вам четыре параметра, чтобы вы могли точно настроить процесс проверки. Первый параметр определяет действие, которое выполняется с nonce. Оно не выводится в поле, оно содержится в хэше. Второй параметр изменяет имя, которое по умолчанию задается как _wpnonce. Третий параметр – логическая переменная, которая проверяет, выбран или нет реферер (по умолчанию true). Наконец, четвертый параметр – это логическая переменная, которая определяет, выводится или нет поле (по умолчанию true).
Важное правило, которое надо соблюдать: имя действия должно быть максимально специфичным (первый параметр). Не надо просто называть его «delete-post», пусть оно называется «delete-post-[ post_ID ]».
На другом конце действия вы должны проверить nonce. Для этого используется параметр action формы. Чтобы проверить nonce, введите простой код:
if ( ! isset( $_POST['field_name'] ) || ! wp_verify_nonce( $_POST['field_name'], 'action_name' ) ) { // Do something if the nonce does not verify exit(); } // Process your form
Обратите внимание, что это будет работать только в том случае, если ваша форма использует метод post. Вы действительно всегда должны использовать post для важных данных.
Добавление Nonces к URL-адресам
Иногда вам нужно будет инициировать действие с помощью ссылки, особенно в области администратора. Поскольку ссылки по существу передаются как параметры запроса, вы можете легко прикрепить nonce к ссылкам.
Сделать это можно с помощью функции wp_nonce_url(). Вот как:
$delete_link = wp_get_shortlink( get_the_ID() ) . '&delete=true'; $nonced_link = wp_nonce_url( $delete_link, 'delete-post-' . get_the_ID(), '_mynonce' );
В итоге мы получим URL, который будет иметь следующий вид: http://mysite.com?p=553&_mynonce=7278c82a8f3. Как вы можете видеть, это напоминает то, что мы делали с формами; единственное отличие в том, что nonce передаются в URL как GET-параметры.
Вы можете проверить nonce тем же методом, что и раньше. В этот раз давайте добавим соответствующее имя действия с ID и используем GET-переменные:
if ( ! isset( $_GET['_mynonce'] ) || ! wp_verify_nonce( $_GET['_mynonce'], 'delete-post-' . $_GET['p'] ) ) { // Do something if the nonce does not verify exit(); } // Process your form
Заключение
Это было довольно просто, не так ли? И это позволяет добавить неплохой уровень безопасности к вашему продукту.
Nonces должны использоваться всякий раз, когда вы хотите инициировать пользовательское действие, иначе ваше приложение будет уязвимо для всех типов атак.
Помните, что одноразовые числа только проверяют цель. Вам по-прежнему надо удостовериться в том, что пользователь также имеет соответствующие права доступа.
Источник: wpmu.org