MODX Revolution заслуженно считается одной из самых безопасных CMS. За 18 лет работы с этой системой я сталкивался с различными угрозами — от примитивных попыток взлома до серьёзных DDoS-атак. В этой статье поделюсь реальным опытом защиты сайтов и расскажу, как обеспечить максимальную безопасность вашего MODX-проекта.

Почему MODX безопаснее конкурентов

Архитектурные преимущества

MODX изначально проектировался с учётом безопасности. В отличие от WordPress с его «макаронным» кодом, где PHP, JavaScript и HTML переплетаются в один клубок, MODX имеет чёткую архитектуру разделения логики и представления.

Ключевые особенности:

  • Система разрешений на уровне ресурсов и элементов
  • Отсутствие прямого доступа к файлам системы через URL
  • Контролируемое выполнение PHP-кода только в специально отведённых местах
  • Защищённые директории с правильными настройками .htaccess

Реальный опыт: как MODX отражал атаки

За годы работы наблюдал множество попыток взлома сайтов клиентов. Вот несколько показательных случаев:

DDoS-атака на интернет-магазин Сайт на miniShop2 подвергся массированной DDoS-атаке — тысячи запросов в секунду к формам заказа. MODX справился без дополнительной защиты благодаря:

  • Эффективному кешированию запросов
  • Встроенной защите от переполнения форм
  • Правильной настройке лимитов PHP

SQL-инъекции через поисковые формы Злоумышленники пытались внедрить вредоносный код через mSearch2. Попытки провалились из-за:

  • Автоматической экранизации входных данных в xPDO
  • Использования подготовленных запросов
  • Валидации на уровне процессоров

Базовая настройка безопасности

Перемещение системных папок

Первое, что нужно сделать после установки — переместить критически важные папки за пределы веб-корня.

# В .htaccess корневой директории
RewriteEngine On
RewriteRule ^core/ - [F,L]
RewriteRule ^manager/ manager/index.php [L]

Рекомендуемая структура:

/home/user/
├── public_html/
│   ├── assets/
│   ├── connectors/
│   └── index.php
├── modx_core/          # Перемещена из public_html/core/
└── manager/            # Защищена дополнительно

Настройка config.core.php

<?php
define('MODX_CORE_PATH', '/home/user/modx_core/');
define('MODX_CONFIG_KEY', 'config');

Защита административной панели

1. Изменение URL менеджера

// В config/core.php
$modx_manager_path = '/secret_admin_path/';

2. HTTP Basic Auth для менеджера

# В manager/.htaccess
AuthType Basic  
AuthName "Admin Area"
AuthUserFile /path/to/.htpasswd
Require valid-user

3. Ограничение по IP

<RequireAll>
    Require ip 192.168.1.100
    Require ip 203.0.113.0/24
</RequireAll>

Система разрешений и пользователи

Принцип минимальных привилегий

// Создание роли контент-менеджера
$policy = $modx->newObject('modAccessPolicy');
$policy->set('name', 'ContentManager');
$policy->set('description', 'Управление контентом без системных настроек');
$policy->set('data', json_encode([
    'resource_list' => true,
    'resource_edit' => true,
    'resource_create' => true,
    'element_tv_edit' => true,
    // Запрещены системные операции
    'settings' => false,
    'packages' => false,
    'sources' => false
]));

Настройка контекстов безопасности

// Отдельный контекст для админки
$adminContext = $modx->newObject('modContext');
$adminContext->set('key', 'admin');
$adminContext->set('description', 'Административный контекст');

// Настройки контекста
$settings = [
    'site_url' => 'https://admin.example.com/',
    'base_url' => '/',
    'error_page' => 1,
    'unauthorized_page' => 2
];

Защита от популярных угроз

SQL-инъекции

MODX использует xPDO ORM, который автоматически экранирует данные:

// ПРАВИЛЬНО - безопасное получение данных
$userId = (int) $_GET['user_id'];
$user = $modx->getObject('modUser', $userId);

// ЕЩЁ ЛУЧШЕ - с дополнительной проверкой
$userId = $modx->getOption('user_id', $_GET, 0, 'is_int');
if ($userId > 0) {
    $user = $modx->getObject('modUser', $userId);
}

// НЕПРАВИЛЬНО - уязвимый код
$query = "SELECT * FROM users WHERE id = " . $_GET['user_id'];

XSS-атаки

// В сниппетах всегда экранируем вывод
$output = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');

// Для пользовательского контента
$cleanContent = $modx->sanitizeString($userContent);

// В шаблонах используем фильтры
[[*content:htmlent]]
[[+userInput:strip_tags]]

CSRF-защита

// В формах добавляем токен
$token = $modx->user->getUserToken($modx->context->get('key'));
echo '<input type="hidden" name="csrf_token" value="' . $token . '">';

// Проверка в процессоре
if (!$modx->user->validateUserToken($scriptProperties['csrf_token'], $modx->context->get('key'))) {
    return $modx->error->failure('Ошибка безопасности');
}

Обновления и мониторинг

Стратегия обновлений

1. Тестовое окружение

# Создание копии продакшена
rsync -av --exclude-from=exclude.txt production/ staging/
mysqldump production_db | mysql staging_db

2. Поэтапное обновление

  • Сначала дополнения и компоненты
  • Затем ядро MODX
  • Проверка совместимости после каждого этапа

3. План отката

// Скрипт быстрого отката
$backup_date = '2026-02-28_14-30';
exec("mysql database < backups/db_$backup_date.sql");
exec("rsync -av backups/files_$backup_date/ ./");

Автоматизированный мониторинг

// Сниппет проверки целостности системы
class SecurityMonitor {
    public function checkCoreFiles() {
        $coreFiles = [
            MODX_CORE_PATH . 'config/config.inc.php',
            MODX_CORE_PATH . 'model/modx/modx.class.php'
        ];
        
        foreach ($coreFiles as $file) {
            if (!file_exists($file)) {
                $this->alert('Отсутствует критический файл: ' . $file);
            }
            
            $hash = md5_file($file);
            if ($hash !== $this->getExpectedHash($file)) {
                $this->alert('Изменён системный файл: ' . $file);
            }
        }
    }
    
    public function checkLoginAttempts() {
        $threshold = 10; // максимум попыток за час
        $attempts = $modx->getCount('modUserLog', [
            'action' => 'login_failed',
            'occurred:>' => strtotime('-1 hour')
        ]);
        
        if ($attempts > $threshold) {
            $this->lockdown();
        }
    }
}

Резервное копирование

Автоматизированная система бэкапов

#!/bin/bash
# backup_modx.sh

DATE=$(date +"%Y-%m-%d_%H-%M")
BACKUP_DIR="/backups/$DATE"
SITE_DIR="/home/user/public_html"
DB_NAME="modx_database"

# Создание директории
mkdir -p $BACKUP_DIR

# Бэкап базы данных
mysqldump --single-transaction --routines --triggers $DB_NAME > $BACKUP_DIR/database.sql

# Бэкап файлов (исключая кеш и временные файлы)
rsync -av --exclude='core/cache/' --exclude='core/logs/' $SITE_DIR/ $BACKUP_DIR/files/

# Проверка целостности
if [ -s $BACKUP_DIR/database.sql ] && [ -d $BACKUP_DIR/files ]; then
    echo "Бэкап создан успешно: $BACKUP_DIR"
    
    # Удаление старых бэкапов (старше 30 дней)
    find /backups -type d -mtime +30 -exec rm -rf {} \;
else
    echo "ОШИБКА: Бэкап не создан!"
    exit 1
fi

Настройка cron для автобэкапов

# Ежедневный бэкап в 3:00
0 3 * * * /path/to/backup_modx.sh

# Еженедельный полный бэкап в воскресенье в 2:00
0 2 * * 0 /path/to/full_backup_modx.sh

Лучшие практики безопасности

Чек-лист базовой защиты

Файловая система:

  • Системные папки перенесены из веб-корня
  • Права доступа настроены корректно (755 для папок, 644 для файлов)
  • .htaccess файлы защищают критичные директории

База данных:

  • Используется отдельный пользователь с минимальными правами
  • Префикс таблиц изменён с стандартного
  • Настроено шифрование соединений

Учётные записи:

  • Администраторский аккаунт переименован
  • Используются сложные пароли
  • Включена двухфакторная аутентификация

Конфигурация хостинга

При выборе хостинга обращайте внимание на:

PHP настройки:

  • disable_functions должна включать опасные функции
  • open_basedir ограничивает доступ к файловой системе
  • Актуальная версия PHP с последними патчами безопасности

Рекомендую Timeweb — у них хорошо настроенная безопасность для MODX и круглосуточная техподдержка.

Реагирование на инциденты

План действий при взломе

1. Немедленные действия:

# Блокировка сайта
echo "Сайт временно недоступен" > index.html

# Создание слепка для анализа
cp -r /site /forensic_copy_$(date +%Y%m%d_%H%M)

# Смена паролей
mysql -u root -p -e "UPDATE modx_users SET password = MD5('new_temp_password') WHERE username = 'admin'"

2. Анализ и восстановление:

  • Изучение логов доступа и ошибок
  • Поиск изменённых файлов
  • Проверка целостности базы данных
  • Восстановление из проверенной резервной копии

Превентивные меры

// Мониторинг изменений файлов
class FileIntegrityChecker {
    private $hashFile = 'core/cache/file_hashes.json';
    
    public function updateHashes() {
        $files = $this->getCriticalFiles();
        $hashes = [];
        
        foreach ($files as $file) {
            $hashes[$file] = md5_file($file);
        }
        
        file_put_contents($this->hashFile, json_encode($hashes));
    }
    
    public function checkIntegrity() {
        $storedHashes = json_decode(file_get_contents($this->hashFile), true);
        $changes = [];
        
        foreach ($storedHashes as $file => $hash) {
            if (!file_exists($file) || md5_file($file) !== $hash) {
                $changes[] = $file;
            }
        }
        
        if (!empty($changes)) {
            $this->notifyAdmin($changes);
        }
    }
}

Заключение

Безопасность MODX — это не одноразовая настройка, а постоянный процесс. Система даёт отличные инструменты защиты из коробки, но их нужно правильно использовать.

Основные принципы:

  1. Минимизация атаки поверхности — скрывайте всё, что можно скрыть
  2. Глубокая защита — используйте несколько уровней безопасности
  3. Регулярное обслуживание — обновления, мониторинг, бэкапы
  4. Подготовка к худшему — план восстановления должен быть отработан заранее

MODX позволяет создавать действительно безопасные сайты без лишних сложностей. В отличие от других CMS, здесь не нужно устанавливать десятки плагинов безопасности — большинство защит работает на уровне ядра.


Связанные статьи: SEO-продвижение сайтов на MODX

Автор материала

Антон Ветров Разработка сайтов, поисковая доступность, автоматизация и эксплуатация.