Пользователи в WordPress: пять ошибок, которые дорого стоят
Шесть администраторов, открытый список авторов и удалённый сотрудник вместе с его записями. Разбираем пять ошибок с пользователями WordPress 6.x, их цену и то, чем их заменить.

Знакомая картина для WordPress 6.x через пару лет: шесть учётных записей с ролью «Администратор». Владелец, подрядчик, сдавший проект год назад, контент-менеджер и аккаунт admin с ID 1. Каждый из них на обычной установке может поставить плагин, а значит запустить свой PHP-код на вашем сервере. Разбираем пять ошибок с пользователями и ролями: сколько они стоят и чем их заменить.
Что умеют стандартные роли
На одиночной установке пять ролей. Главное отличие каждой:
- Administrator: всё, включая плагины, темы, настройки и пользователей.
- Editor: публикует и правит любые записи и страницы, модерирует комментарии. Может вставлять сырой HTML и скрипты (право
unfiltered_html). - Author: публикует и правит только свои записи, загружает файлы.
- Contributor: пишет и правит свои записи, но не публикует их и не загружает файлы.
- Subscriber: только профиль.
В мультисайте добавляется Super Admin, и установка плагинов доступна только ему.
Сноска. Capability (право) это отдельное разрешение вроде publish_posts или manage_options. Роль только именованный набор таких прав.
Роль ничего не защищает: это ярлык на наборе прав. Защищает проверка права на конкретное действие.
Ошибка 1. Администратор для всех
Эту роль выдают, чтобы никто не писал «мне не хватает прав». Цена приходит позже: подобранный пароль любого администратора открывает установку плагина, то есть произвольный код на сервере. Правку файлов тем и плагинов из консоли закрывает строка define( 'DISALLOW_FILE_EDIT', true ); в wp-config.php. Константа DISALLOW_FILE_MODS идёт дальше и блокирует установку и обновления из админки. В ядре нет журнала действий, поэтому кто и что менял, не восстановить.
Четыре способа выдать доступ
| Подход | Что выигрываете | Чем платите |
|---|---|---|
| Administrator всем | Ничего не нужно настраивать | Один утёкший пароль открывает установку плагинов; действия не отследить |
| Стандартная роль | Без кода, роли знакомы всем | Набор прав фиксирован; у Editor есть unfiltered_html |
Своя роль через add_role | Точный набор прав, лежит в git, повторяется на staging | Нужен разработчик; права для типов записей из плагинов проверять вручную |
| Плагин-редактор ролей | Правка из админки без кода | Роль живёт только в базе, расходится со staging, остаётся после удаления плагина |
Своя роль, записанная один раз
Роли лежат в базе (опция wp_user_roles при префиксе wp_), поэтому add_role вызывают при активации плагина, а не на каждом запросе. Роль ниже без unfiltered_html: скрипты и iframe из записей будут вычищаться. Для страниц нужны отдельные права, например edit_pages.
<?php
/**
* Plugin Name: Роль Контент-менеджер
* Version: 1.0.0
*/
// Роль записывается в базу один раз, при активации плагина.
register_activation_hook( __FILE__, function () {
add_role(
'content_manager',
'Контент-менеджер',
array(
'read' => true,
'edit_posts' => true,
'edit_others_posts' => true,
'edit_published_posts' => true,
'publish_posts' => true,
'upload_files' => true,
)
);
} );
Ошибка 2. Логин виден снаружи
Два адреса отдают имена авторов без авторизации. Адрес /?author=1 при человекопонятных ссылках перенаправляет на /author/слаг/, а /wp-json/wp/v2/users возвращает пользователей с опубликованными записями: поля id, name и slug. Слаг (user_nicename) создаётся из логина и обычно на него похож. Масштаб честный: логин доступа не даёт, но атакующему остаётся подбирать только пароль. Настоящая защита: длинный пароль, лимит попыток входа и двухфакторная аутентификация, которой в ядре 6.x нет.
Что сделать: в профиле выберите отображаемое имя, не совпадающее с логином. Слаг меняется командой wp user update USER_ID --user_nicename=NEW_SLUG. Сам логин в интерфейсе не меняется, для admin заведите нового пользователя. Список в REST закрывает фильтр. Положите его в отдельный плагин или mu-plugin, не в functions.php темы: смена темы вернёт утечку.
<?php
// Закрывает список пользователей в REST API для гостей.
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. Удаление без передачи записей
Диалог удаления предлагает два варианта: удалить весь контент или назначить его другому пользователю. Первый удаляет записи ушедшего сотрудника. Считайте операцию необратимой и сделайте бэкап. В WP-CLI то же делает флаг --reassign: wp user delete 7 --reassign=2. Если на старых материалах нужна подпись автора, не удаляйте аккаунт: понизьте роль до Subscriber, смените пароль и завершите сессии в профиле.
Ошибка 4. Открытая регистрация с лишней ролью
В «Настройки → Общие» два параметра: «Любой может зарегистрироваться» (опция users_can_register) и «Роль нового пользователя по умолчанию» (default_role). Если регистрация открыта, а роль выше Subscriber, права получает каждый, кто заполнил форму. Так бывает после правки «на минутку» или из-за плагина членства. Регистрация не нужна: выключите. Нужна: оставьте Subscriber и повышайте вручную.
Ошибка 5. Проверка по ID и имени роли
Проверка по ID или имени роли ломается при смене роли на свою и в мультисайте: у суперадминистратора роли на подсайте может не быть. Проверяйте право, нужное для действия.
<?php
// Хрупко: ID 1 может смениться, а роли у суперадмина на подсайте может не быть.
$user = wp_get_current_user();
$allowed = ( 1 === $user->ID ) || in_array( 'administrator', $user->roles, true );
// Надёжно: проверяется право на действие.
$allowed = current_user_can( 'manage_options' );
// Для конкретной записи: право на неё.
$post_id = 42; // пример
$can_edit = current_user_can( 'edit_post', $post_id );
Когда что выбирать
- Человек правит чужие материалы и не вставляет HTML: Editor. Если вставлять HTML нельзя, нужна своя роль, как выше.
- Пишет только своё: Author. Публиковать сам не должен: Contributor.
- Нужен набор, которого нет среди пяти, а код живёт в git:
add_roleв плагине. - Разово на одном сайте и без разработчика: плагин-редактор, но выпишите итоговый набор прав в документацию сайта.
- Administrator: только тем, кто ставит плагины и меняет настройки и кого можно назвать по имени.
Что ломается
- Смена префикса таблиц без переименования опции
wp_user_rolesи ключей usermetawp_capabilities: администратор видит «Sorry, you are not allowed to access this page». - Закрытый
/wp/v2/usersломает плагины и фронтенды, которые подтягивают авторов через REST для гостей. add_capна каждом запросе возвращает права после ручных правок в редакторе ролей.remove_roleоставляет пользователей без прав: сначала переведите их на другую роль.- Скрипт ходит в REST под паролем администратора. Заведите отдельного пользователя с минимальной ролью и выпустите ему пароль приложения (WordPress 5.6+, по умолчанию только по HTTPS). Его можно отозвать, не меняя пароль входа.
Что делать дальше
- Выведите список администраторов командой из блока ниже.
- Спросите про каждого: ставит ли он плагины? Нет: переведите в Editor или свою роль.
- Проверьте регистрацию и роль по умолчанию.
- Добавьте
DISALLOW_FILE_EDIT, закройте список пользователей в REST, смените отображаемые имена. - Повторяйте аудит раз в квартал.
# Администраторы сайта
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
# Перевести пользователя 5 в роль editor
wp user set-role 5 editor
# Регистрация и роль по умолчанию
wp option get users_can_register
wp option get default_role
Лимит попыток входа и двухфакторная аутентификация это отдельная тема. Следите за двумя числами: сколько учётных записей имеют право manage_options и сколько неудачных входов в неделю фиксирует ваш журнал входов, если он есть.
Аналитик звонков: Разбор записи звонка по этапам сделки: где сорвалось, что упущено, три исправляемые рекомендации с цитатами.
Спросить за 90 ₽Источники: WordPress Plugin Handbook: Roles and Capabilities, WordPress REST API Handbook: Users
Частые вопросы
Как переименовать логин admin?
А если у меня другая версия WordPress?
А если после правок пропал доступ в админку?
Достаточно ли закрыть /wp-json/wp/v2/users?
Что учесть в проде при добавлении ролей через код?
Как дать скрипту доступ к REST API без пароля администратора?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.