Прежде чем подбирать пароль, злоумышленнику нужно узнать имя пользователя. На стандартном сайте WordPress получить его проще простого, и для атакующего это не стоит ровным счетом ничего. Поэтому первое, что я проверяю на переданном мне сайте, — это то, сколько имен пользователей он отдаёт даром.
Существует четыре основных пути раскрытия. Вы можете проверить каждый из них с помощью curl с устройства, на котором не выполнена авторизация.
1. Архив автора
Запросите автора по его числовому ID, и WordPress перенаправит вас на архив этого автора, содержащий логин прямо в URL:
curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" "https://example.com/?author=1"
Ответ 301 на запрос https://example.com/author/johnd/ только что сообщил вам, что пользователь с ID 1 логинится как johnd . Бот просто перебирает ID по порядку, начиная с 1, и собирает все имена, на которые происходит редирект.
Решение (если вы специально не публикуете страницы авторов) — отклонять запросы к архивам авторов для неавторизованных посетителей:
<?php
add_action( 'template_redirect', function () {
if ( is_author() && ! is_user_logged_in() ) {
wp_redirect( home_url(), 301 );
exit;
}
} );
Если же вы используете страницы авторов, измените базовый URL авторов и публичный слаг вместо полной их блокировки.
2. Эндпоинт users в REST API
curl -s "https://example.com/wp-json/wp/v2/users" | head
JSON-массив с id , name и slug для каждого автора — это та же самая утечка, но в более удобной обёртке. Проверяйте и вариант с query-параметрами, так как блокировка, настроенная только на /wp-json/ , пропустит его:
curl -s -o /dev/null -w "%{http_code}\n" "https://example.com/?rest_route=/wp/v2/users"
Отключите эндпоинты пользователей для гостей с помощью фильтра rest_endpoints :
<?php
add_filter( 'rest_endpoints', function ( $endpoints ) {
if ( ! is_user_logged_in() ) {
unset( $endpoints['/wp/v2/users'] );
unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
}
return $endpoints;
} );
3. Встроенная карта сайта (sitemap)
Начиная с версии WordPress 5.5, в встроенной карте сайта появился раздел пользователей:
curl -s -o /dev/null -w "%{http_code}\n" "https://example.com/wp-sitemap-users-1.xml"
Запрос 200 отображает список ваших авторов для любого желающего и для поисковых систем. Отключите именно этот провайдер:
<?php
add_filter( 'wp_sitemaps_add_provider', function ( $provider, $name ) {
return ( 'users' === $name ) ? false : $provider;
}, 10, 2 );
4. Форма входа
Этот способ проверяется вручную, а не через curl. Введите несуществующее имя, и WordPress выведет: «The username is not registered». Введите имя существующего пользователя с неверным паролем, и появится сообщение: «The password you entered is incorrect». В этой разнице и кроется подтверждение реальных логинов. Настройте форму так, чтобы в обоих случаях выводилось одно и то же общее сообщение.
Ошибка, сводящая на нет защиту трёх предыдущих путей
Если ваш логин — john , и в подписи к каждой статье отображается john , перекрытие трёх вышеописанных путей мало что даст. Имя пользователя и так выведено на странице. Откройте свой профиль, установите публично отображаемое имя, отличающееся от логина, и по возможности создавайте аккаунт с логином, который изначально не является настоящим именем.
Зачем этим заниматься, если имя пользователя — это лишь половина данных для входа?
Потому что подобрать вторую половину намного проще, когда имя уже известно. В отчете Verizon Data Breach Investigations Report за 2025 год украденные учетные данные фигурировали в 88% базовых атак на веб-приложения. Зная реальное имя пользователя, атакующий переходит от перебора по тысячам аккаунтов к точечной атаке на один конкретный профиль — как правило, администратора.
Проведите эти четыре проверки на одном из своих сайтов прямо сегодня, затем повторите их после исправления и сохраните результаты до и после. А какие еще способы утечки имени пользователя в WordPress вы встречали, помимо описанных в статье?
Комментарии (0)
Пока нет комментариев — будьте первым.