Можно ли предотвратить перечисление имен пользователей?
Можно ли предотвратить перечисление имен пользователей на моем WordPress сайте? В данный момент я вижу, что пользователи обнаруживаются с помощью инструмента WPScan.

Простое решение, которое я использую в файле .htaccess
:
RewriteCond %{REQUEST_URI} !^/wp-admin [NC]
RewriteCond %{QUERY_STRING} author=\d
RewriteRule ^ - [L,R=403]
Оно похоже на ответ @jptsetme, но работает даже когда строка запроса имеет вид /?dummy&author=5
, а шаблон поиска для RewriteRule
выполняется очень быстро: часто можно встретить захват ([0-9]*)
в регулярных выражениях для этого случая. Но нет необходимости тратить память на захват, если вы не используете захваченное выражение, и достаточно совпадения по первому символу, так как вы не хотите принимать значения вида author=1b
.
Обновление от 20.04.2017
Я наблюдаю всё больше "некорректных" запросов от людей, которые даже не могут правильно запустить простой сканинг. Запрашиваемые URL выглядят следующим образом:
/?author={num:2}
Поэтому вы можете расширить приведённое выше правило до:
RewriteCond %{REQUEST_URI} !^/wp-admin [NC]
RewriteCond %{QUERY_STRING} ^author=\d+ [NC,OR]
RewriteCond %{QUERY_STRING} ^author=\{num
RewriteRule ^ - [L,R=403]

Вы не можете этого предотвратить.
Инструмент WPScan — это автоматизированная утилита, которая использует дружественные URL WordPress для определения имен пользователей. Он перебирает первые 10 возможных ID авторов и проверяет заголовок Location
в HTTP-ответе, чтобы найти имя пользователя.
Например, используя http://mysite.url
...
WPScan проверит http://mysite.url/?author=1
. Если ваш сайт использует "красивые" постоянные ссылки, он вернет 301 редирект с заголовком Location
, содержащим http://mysite.url/author/username
. Если ваш сайт не использует "красивые" ссылки, он вернет статус 200 (OK), и тогда WPScan проверит ленту на наличие строки "posts by username" и извлечет имя пользователя.
Что можно сделать
Прежде всего, даже если кто-то может угадать ваше имя пользователя, это не означает, что ваш сайт небезопасен. И по сути, нет способа предотвратить подобный парсинг сайта.
Однако ...
Если вас это действительно беспокоит, я рекомендую сделать две вещи:
- Отключить "красивые" постоянные ссылки. Это заставит WPScan и подобные инструменты анализировать контент сайта для поиска имен пользователей, а не полагаться на URL.
- Заставить пользователей устанавливать разные никнеймы. При отсутствии имени пользователя в URL инструменты сканирования будут искать "posts by username" в ленте или содержимом постов. Если вы не публикуете имена пользователей, их нельзя будет получить.
Еще один вариант — изменить правила перезаписи ссылок на авторов. Есть несколько способов сделать это, и вы, вероятно, найдете несколько на этом сайте.

Не тестировал это тщательно, но думаю, что предпочтительнее удалить базовый ресурс, чем пытаться строить стены вокруг него на уровне веб-сервера. В терминах WordPress это означало бы прекращение обработки переменных запроса, связанных с авторами.
if ( ! is_admin() ) {
add_filter(
'query_vars',
function ( $public_query_vars ) {
foreach ( array( 'author', 'author_name' ) as $var ) {
$key = array_search( $var, $public_query_vars );
if ( false !== $key ) {
unset( $public_query_vars[$key] );
}
}
return $public_query_vars;
}
);
}
Примечание: это полностью отключит архивы авторов, что может быть или не быть подходящим уровнем паранойи :)

Вы можете использовать правило перезаписи в файле .htaccess, чтобы предотвратить эту утечку информации, но также следует использовать псевдонимы, чтобы избежать раскрытия имен пользователей в анализируемом контенте, как описано EAMann.
Следующий блог описывает, как это сделать, но содержит опечатку в правиле перезаписи: http://www.question-defense.com/2012/03/20/block-wordpress-user-enumeration-secure-wordpress-against-hacking
Правильное правило также должно удалять строку запроса из перезаписанного URL, иначе имя пользователя все равно будет раскрыто. Оно должно выглядеть так:
# Прекращение уязвимости перечисления имен пользователей WordPress
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{QUERY_STRING} ^/?author=([0-9]*)
RewriteRule ^(.*)$ http://yoursite.com/somepage/? [L,R=301]
Хорошо работает для нас.

Я хотел добавить, что это можно сделать и на nginx. Проверьте:
» Блокировка перечисления пользователей WordPress на nginx - www.edwidget.name
Кроме того, я хотел предотвратить перечисление имен пользователей на моем сайте, размещенном на WP Engine, который ограничивает доступ пользователей к низкоуровневым конфигурационным файлам nginx. Однако у них есть раздел "Правила перенаправления" в панели управления, который позволяет добиться этого. После некоторых усилий я определил оптимальную конфигурацию:
Название перенаправления: // выберите описание для правила перезаписи
Домен: // обязательно выберите домен; вариант "Все домены" здесь *не* сработает!
Источник: ^/$
Назначение: /?
Затем вам нужно открыть панель Дополнительные настройки
...
Сопоставить аргументы: author=([0-9]*)
Тип перезаписи: 301 Постоянное
И вуаля, ваши имена пользователей стали безопаснее!

Я полностью заблокировал перебор пользователей через WPScan, добавив следующее в htaccess
# Защита от перебора имен пользователей в WordPress
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{QUERY_STRING} ^/?author=([0-9]*)
RewriteRule ^(.*)$ http://yourdomain.com [L,R=301]
RewriteCond %{QUERY_STRING} author=d
RewriteRule ^ /? [L,R=301]
Мое профессиональное мнение как пентестера для госучреждения... ВСЕГДА стоит усложнять сбор информации о вашем сайте. У немногих из вас сайт будет интересен серьезным хакерам, а не просто скрипт-кидди из Google. Речь идет о многоуровневой безопасности — каждый новый уровень добавляет времени и сложности для взлома. Каждый уровень также требует от хакера более высоких навыков. Для WordPress есть несколько хороших брандмауэров приложений. Ищите те, которые могут блокировать IP-адреса после множества неудачных попыток входа или 404 ошибок. Идея в том, чтобы ваш брандмауэр автоматически блокировал IP, которые сканируют сайт на наличие несуществующих страниц или пытаются многократно войти. Хорошая функция — также защита от XSS и SQL-инъекций. Рекомендую плагин All In One WP Security от Tips and Tricks HQ (Peter, Ruhul, Ivy). У него удобный интерфейс и функционал как для новичков, так и для экспертов.

Вместо маршрута через .htaccess
, альтернативным вариантом является добавление следующего кода в файл functions.php
вашей дочерней темы:
# Перенаправление страницы автора на главную страницу
add_action( 'template_redirect', 'wpse_46469_author_page' );
function wpse_46469_author_page() {
# Если происходит доступ к архивной странице автора, перенаправить на главную страницу
if ( is_author() ) {
wp_safe_redirect( get_home_url(), 301 );
exit;
}
}
Дополнительно, вы можете изменить стандартные ссылки автора, которые добавляются к имени пользователя на каждой странице, на что-то другое (например, на главную страницу), используя следующий код:
# Замена URL автора на главную страницу
add_filter( 'author_link', 'wpse_46469_author_link' );
function wpse_46469_author_link() {
# Возвращаем URL главной страницы
return home_url();
}

Я знаю, что это старый пост, но для будущих читателей я хочу добавить и своё решение. Это всего лишь фрагмент кода, который нужно поместить в файл functions.php
вашей темы. Он оставит всё на своих местах и работающим, включая архивы авторов, но устранит нежелательные запросы перечисления.
if (!is_admin()) {
if( preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING']) ) {
add_filter( 'query_vars', 'iside_remove_author_from_query_vars' );
}
add_filter('redirect_canonical', 'iside_remove_author_from_redirects', 10, 2);
}
function iside_remove_author_from_redirects($redirect, $request) {
if( !is_admin() && preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING']) ) {
add_filter( 'query_vars', 'iside_remove_author_from_query_vars' );
}
return $redirect;
}
function iside_remove_author_from_query_vars( $query_vars ) {
if( !is_admin() ) {
foreach( array( 'author', 'author_name' ) as $var ) {
$key = array_search( $var, $query_vars );
if ( false !== $key ) {
unset( $query_vars[$key] );
}
}
}
return $query_vars;
}
Что делает этот код:
- Он сканирует URL на наличие параметров вида:
author=1
- При обнаружении удаляет переменную автора из query vars, чтобы запрос не выполнялся.
Если вы используете постоянные ссылки (permalinks), архивы авторов останутся работоспособными. Также, если URL будет вида /dummy?author=1
, он просто покажет страницу /dummy
.
Спасибо ответу Rarst на этот вопрос и https://perishablepress.com/stop-user-enumeration-wordpress/

Я хочу изложить своё видение:
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{QUERY_STRING} author=(\%|\+|\d) [NC]
RewriteRule (.*) $1? [L]
Первая строка проверяет только главную страницу. Объясню почему. Эта функция "перечисления пользователей" работает только на главной, поэтому нет необходимости переписывать все URL.
Далее мы ищем строку запроса author=
. Это очевидно.
В конце мы просто показываем оригинальную страницу без каких-либо блокировок, редиректов (301, 302) или банов (403). Разве она не должна вести себя как страница с любым другим бесполезным параметром?
