RE:NODE

Веб-хостинг12 мин чтения

Защита WordPress: меры, на которые стоит тратить силы

Политика обновлений, входы, права на файлы, xmlrpc, порядок с плагинами и резервные копии: защита WordPress, которая останавливает реальные атаки, и показуха, которую стоит пропустить.

0 прочтений

Взлом сайта на WordPress обычно происходит не через ядро. Входом служит устаревший плагин с публичным бюллетенем уязвимости, пароль, повторно использованный там, откуда он утёк, или файл, который веб-серверу никогда не следовало позволять записывать. Защита, которая игнорирует эти три пути и вместо этого прячет номер версии в исходном коде страницы, - просто украшение.

Поэтому вот честный порядок: держите всё обновлённым, сделайте вход бесполезным для атакующего, не давайте PHP запускаться там, где ему нечего делать, ставьте меньше плагинов и только от тех, кто их ещё поддерживает, и храните резервные копии там, куда взлом не дотянется. Всё написанное ниже относится к одному из этих пяти пунктов, а где популярный совет ничего не даёт, об этом сказано прямо.

Как на самом деле взламывают сайты на WordPress#

Четыре пути объясняют почти всё.

  • Уязвимый плагин или тема. Кто-то публикует бюллетень, автоматические сканеры в течение часов начинают проверять каждый сайт в интернете на наличие пути этого плагина, и сайты, не обновлявшиеся неделю, находятся. Это самая крупная категория, и это целиком проблема установки патчей.
  • Учётные данные. Подбор пароля к wp-login.php, но чаще - credential stuffing с паролем, утёкшим из постороннего сервиса. Также украденные учётные данные SFTP или панели, что обычно означает, что скомпрометирован был ноутбук владельца, а не сервер.
  • Заброшенные или проданные плагины. Плагин с 40 000 установок перестаёт поддерживаться или переходит в другие руки, и новый владелец выпускает обновление, загружающее удалённый код. Случается редко и неприятно, потому что атакой является само обновление.
  • Соседи. На виртуальном хостинге с небрежной изоляцией взлом одного сайта доходит до следующего через файлы с правами записи для всех или общего пользователя базы данных. Хостинг с отдельным контейнером на сайт снимает эту проблему, и это реальное различие между моделями хостинга, а не рекламная строка.

Обратите внимание, чего здесь нет: zero-day в самом WordPress. Ядро тщательно проверяется, быстро получает релизы безопасности и устанавливает их само. Если ваш сайт взломан, сначала посмотрите на список плагинов и журналы доступа, а потом уже на ядро.

Обновления и какие из них автоматизировать#

Начиная с версии 3.7 WordPress сам устанавливает свои минорные релизы и релизы безопасности. Оставьте это как есть. Константа, которая этим управляет, лежит в wp-config.php и имеет три осмысленных значения:

wp-config.php
define( 'WP_AUTO_UPDATE_CORE', 'minor' );

'minor' - значение по умолчанию и верный ответ почти для всех: 6.7.1 в 6.7.2 обновляется само, а 6.7 в 6.8 ждёт вас. true принимает и мажорные версии автоматически, что нормально для простого сайта и рискованно для сайта с конструктором страниц. false отключает обновления ядра полностью и оправдано только в том случае, если что-то другое применяет их в течение суток.

Автообновления плагинов и тем задаются для каждого элемента отдельно и переключаются на экране Plugins начиная с WordPress 5.5. Рабочая политика:

ЭлементАвтообновлениеПричина
Ядро: минорные и обновления безопасностиДаЗа годы ничего существенного не сломали
Плагины безопасности и служебныеДаОкно между бюллетенем и атаками измеряется часами
Конструктор страниц, тема, WooCommerceНетОбновляйте осознанно, после резервной копии
Всё кастомное или пропатченноеНетОбновление перезапишет ваши изменения

Всё, что вы не автоматизируете, вам придётся делать по-настоящему. Очередь обновлений, которую никто не разбирает, хуже автообновлений, потому что создаёт иллюзию контроля. Поставьте в календарь повторяющуюся задачу, сверяйте её с бюллетенями по плагинам, которыми пользуетесь, и делайте резервную копию непосредственно перед каждой партией, чтобы «обновление сломало сайт» было пятиминутной проблемой.

Страница входа и учётные записи за ней#

В ядре WordPress нет двухфакторной аутентификации, поэтому добавьте её плагином и потребуйте от всех с ролью администратора или редактора. Это единственное изменение делает утечки паролей в основном неважными, и это самая большая отдача за десять минут работы.

Затем снизьте ценность самой страницы входа:

  1. Никаких учётных записей `admin`, `administrator` или с названием сайта. Именно эти три и используют автоматические попытки. Создайте нового администратора, войдите под ним, удалите старого и передайте его записи.
  2. Уникальные пароли, сгенерированные и хранимые в менеджере. Пароль, который заодно открывает аккаунт на форуме 2016 года, паролем не является.
  3. Ограничьте число попыток входа. Это делает любой из плагинов для ограничения входов: несколько неудач с одного адреса, затем блокировка. Credential stuffing из тысяч попыток в минуту превращается в то, что занимает годы.
  4. Разделяйте роли и людей. Авторам и редакторам администратор не нужен. Учётная запись, которая может устанавливать плагины, - это учётная запись, которая может установить бэкдор.
  5. Раз в месяц просматривайте список пользователей. Удаляйте тех, кто ушёл. Спящая учётная запись администратора разработчика, с которым вы работали в 2023 году, - это уязвимость, за которой никто не следит.

Пароли приложений, добавленные в WordPress 5.6, - правильный способ дать внешнему инструменту доступ к REST API: один пароль на интеграцию, отзываемый по отдельности и бесполезный для входа в админку. Если плагин просит у вас настоящий пароль от вашей учётной записи, чтобы подключить сервис, это повод не доверять плагину.

Смена адреса страницы входа плагином - это скрытие, а не безопасность, и оно ломает сценарии, ожидающие wp-login.php. Оно действительно уменьшает объём мусора в ваших логах, и это имеет некоторую ценность на небольшом тарифе, где такие запросы стоят CPU. Оценивайте это по данному критерию, а не по безопасности. Блокировка /wp-admin и /wp-login.php для всех, кроме списка известных адресов, - настоящая версия этой идеи, и она превосходна, когда у вашей команды есть постоянные адреса.

XML-RPC, REST API и перебор пользователей#

xmlrpc.php - старый удалённый интерфейс. Его всё ещё используют мобильное приложение, Jetpack и несколько инструментов публикации, и если ничто в вашем стеке им не пользуется, его стоит закрыть. Он привлекает два вида трафика: подбор паролей и злоупотребление pingback, когда ваш сайт заставляют отправлять запросы третьей стороне.

nginx
location = /xmlrpc.php {    deny all;    access_log off;}

На Apache эквивалент помещается в .htaccess в корне сайта:

.htaccess
<Files "xmlrpc.php">    Require all denied</Files>

REST API - другое дело, и блокировать его целиком нельзя: им пользуется редактор блоков, а также плагины, которые вам важны. Ограничивать стоит перебор пользователей. По умолчанию /wp-json/wp/v2/users перечисляет учётные записи с опубликованными записями, /?author=1 перенаправляет на слаг автора, а wp-sitemap.xml содержит карту авторов. Ничто из этого не является уязвимостью - имя пользователя не секрет, - но всё это бесплатно вручает атакующему первую половину пары учётных данных. Если архивы авторов вам не нужны, плагин для усиления защиты может отключить все три, а отключение карты авторов - это однострочный фильтр.

Другая точка, о которой стоит подумать, - wp-cron.php. WordPress запускает запланированные задачи по запросам посетителей, так что каждый заход может запускать работу cron, а на загруженном сайте атакующие с удовольствием будут запрашивать этот файл в цикле, заставляя PHP снова и снова делать дорогую работу. Задайте define( 'DISABLE_WP_CRON', true ); и вызывайте его по настоящему расписанию: запланированная задача панели, обращающаяся к URL раз в минуту, и быстрее, и дешевле, чем поведение по умолчанию.

Права на файлы и две константы, запирающие админку#

Каталоги с правами 755, файлы - 644, wp-config.php - 640. Никогда не 777: это значит, что любая учётная запись на машине может переписать ваш код. Если что-то не пишет при 755, проблема в владельце, а не в режиме, и chmod 777 - способ превратить проблему прав в взлом.

Две константы убирают большую часть ущерба, который атакующий способен нанести с сессией администратора:

wp-config.php
define( 'DISALLOW_FILE_EDIT', true );define( 'DISALLOW_FILE_MODS', true );

Первая убирает из админки редакторы тем и плагинов - функцию, которая тремя щелчками превращает «украденный пароль» в «произвольный PHP на вашем сервере». Её должен задать каждый. Вторая идёт дальше и полностью блокирует установку и обновление плагинов и тем из панели управления, что верно для сайта, развёртываемого из репозитория, и неверно для сайта, владелец которого обновляет плагины вручную.

Другое правило: ничто в каталоге uploads не должно исполняться. Загруженный файл .php, проскользнувший мимо плохо написанного плагина, бесполезен, если сервер отказывается его запускать:

nginx
location ~* ^/wp-content/uploads/.*\.(?:php|phtml|php5)$ {    deny all;}

Наконец, проверьте, что лежит в корне сайта, чего там быть не должно. Старые файлы wp-config.php.bak, site-backup.zip после миграции, выгруженный database.sql, каталог .git: всё это можно скачать, угадав имя, а сканеры угадывают постоянно. О том же принципе на уровень ниже рассказано в статье правила файрвола, которые важны.

Порядок с плагинами и темами#

Каждый плагин - это код, который вы не писали, работающий с полным доступом к вашей базе данных. Важно не то, сколько их у вас, а сколько из них вы не можете объяснить.

  • Удаляйте, а не деактивируйте. У деактивированного плагина файлы остаются на диске, а несколько исторических уязвимостей эксплуатировались без активного плагина. То же относится к трём стандартным темам, которыми вы не пользуетесь: оставьте одну, остальные удалите.
  • Проверяйте поддержку перед установкой. Дата последнего обновления, версия, на которой проверялся плагин, открытые обсуждения поддержки, число установок. Плагин, обновлявшийся последний раз три года назад, - это решение сопровождать его самому.
  • Никогда не ставьте nulled-темы и плагины. Платный код, ходящий бесплатно, изменён, и изменение и есть бизнес-модель. Это самый надёжный способ оказаться взломанным в первый же день.
  • Предпочитайте один плагин трём. Три плагина, каждый из которых делает треть работы, - это три потока обновлений и три поверхности атаки.
  • Подпишитесь на бюллетени по плагинам, которыми пользуетесь. Базы уязвимостей публикуют ленты; плагин-сканер тоже сообщит, но сообщит постфактум.

Секреты, пользователь базы данных и аккаунт хостинга#

Пользователь базы данных, под которым подключается WordPress, должен иметь полные права на свою базу и никаких прав в остальных местах. Не административная учётная запись и не пользователь, общий со вторым сайтом. Если плагин эксплуатируется через SQL-инъекцию, это разграничение - граница между потерей одного сайта и потерей всех сайтов на аккаунте; рассуждение разобрано в чек-листе безопасности баз данных.

Меняйте соли в wp-config.php после любого подозрения на взлом. Замена этих восьми констант делает недействительными все существующие cookie сессий, в том числе и атакующего. Новые значения берутся по адресу https://api.wordpress.org/secret-key/1.1/salt/.

Затем защитите аккаунт над WordPress, о котором забывают чаще всего. На RE:NODE это означает двухфакторную аутентификацию TOTP на аккаунте панели с резервными кодами, хранящимися там, где они у вас точно останутся, субпользователей с узкими ролями вместо общего логина - только консоль, только файлы, без биллинга - и ключи API, ограниченные по адресу. У каждого сервера свои учётные данные SFTP, а не один ключ аккаунта, открывающий всё, и есть журнал действий по каждому серверу, показывающий, кто что сделал. Обе темы подробно раскрыты в статьях двухфакторная аутентификация для аккаунта панели и субпользователи и минимальные привилегии. Аккаунт, у которого потеряны и аутентификатор, и резервные коды, восстановить нельзя, поэтому храните их раздельно.

Резервные копии, переживающие взлом#

Резервная копия на том же диске, что и сайт, - не резервная копия, а копия, которую вы никогда не восстанавливали, - гипотеза. Для WordPress полная копия состоит из двух половин - файлов в wp-content и базы данных, - и процедура восстановления должна охватывать обе, иначе вы получите сайт, где записи ссылаются на медиафайлы, которых больше нет.

  • Делайте копию перед каждой партией обновлений. Именно эту копию вы и будете использовать, вероятно, в этом же месяце.
  • Держите копии вне машины. Шифровальщик и опрометчивое удаление забирают всё, до чего дотянутся.
  • Проверяйте восстановление на тестовой копии дважды в год. Весь довод изложен в статье проверка восстановления до того, как оно понадобится.
  • Знайте срок хранения. Взлом, обнаруженный тремя неделями позже, требует копии старше трёх недель, а семидневная ротация её обеспечить не может. Храните ежемесячную копию вне ротации.

В веб-тарифы RE:NODE входят слоты резервных копий, создаваемых по требованию или по расписанию на вкладке Schedules, хранимых вне защищаемой машины, восстанавливаемых кнопкой и блокируемых от ротации, а это именно то, что нужно для той ежемесячной копии. Одно ограничение стоит знать заранее: удаление сервера удаляет его резервные копии, в том числе заблокированные, поэтому всё, что должно пережить аккаунт, нужно скачать.

Что делает плагин безопасности и чего не может#

Плагин-сканер и файрвол - Wordfence, Sucuri, Solid Security и подобные - стоит запускать, ясно понимая, что вы получаете. Он может сверять файлы ядра с официальными контрольными суммами и замечать изменённый, оповещать о новых учётных записях администраторов, ограничивать попытки входа и применять виртуальные патчи для известных уязвимостей плагинов до того, как вы обновились.

Он не защитит ни от чего, что происходит до PHP, и сам является PHP: запрос, дошедший до плагина-файрвола, уже загрузил WordPress, так что при наплыве запросов он добавляет работу, а не убирает. Он не увидит взлом, пришедший через ваши учётные данные SFTP и правивший файл с действительной сессией. А его сканер вредоносного кода с завидной регулярностью выдаёт ложные срабатывания на минифицированном JavaScript.

Запускайте его, реагируйте на найденное и не позволяйте ему заменить дисциплину обновлений. Если худшее уже случилось, порядок сдерживания важнее инструментов - последовательность есть в статье что делать, когда ваш сервер взломан: изолировать, сменить все учётные данные, восстановить из копии старше вторжения, затем найти дверь, прежде чем возвращать сайт в сеть.

FAQ#

Улучшает ли безопасность смена префикса таблиц wp_?

Нет. Всё, что может обращаться к вашей базе данных, может перечислить её таблицы, так что префикс не скрыт от атакующего, который уже внутри. Он полезен только для размещения двух сайтов в одной базе, а смена его на живом сайте рискует сломать админку без всякой выгоды.

Стоит ли скрывать номер версии WordPress?

Это ничего не стоит и почти ничего не даёт. Сканеры определяют сайты, проверяя наличие файлов, а не читая тег generator, и атакуют независимо от того, совпадает ли версия. Потратьте усилия на обновления.

Безопасно ли отключать XML-RPC?

Да, если ничто из того, чем вы пользуетесь, в нём не нуждается. Jetpack, мобильное приложение WordPress и некоторые инструменты удалённой публикации нуждаются. Отключите его, затем проверьте, что приложение и плагины по-прежнему работают; если что-то сломалось, разрешите файл и ограничьте частоту запросов, а не оставляйте его открытым нараспашку.

Сколько плагинов - слишком много?

Числа нет. Двадцать хорошо поддерживаемых плагинов безопаснее пяти заброшенных. Настоящий предел - сколько вы способны держать пропатченными и обосновать: если вы не можете сказать, что делает плагин и когда он в последний раз выпускал обновление, он лишний.

Хостинг говорит, что мой сайт рассылает спам. Что делать?

Почти всегда это взлом, установивший скрипт-рассыльщик. Отключите сайт, смените все пароли, включая SFTP и панель, поищите недавно изменённые файлы PHP в wp-content/uploads и wp-content/plugins и восстановитесь из копии, предшествующей изменению, а не удаляйте файлы по одному.

Нужны ли мне резервные копии, если их делает хостинг?

Да. Копии платформы защищают платформу, и на любом хостинге удаление вашего сервера может удалить вместе с ним и его резервные копии. Держите хотя бы одну копию файлов и базы данных там, где вы её контролируете, и знайте, сколько занимает ваше собственное восстановление.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000