Базовая проверка безопасности PHP-сайта
Базовая безопасность PHP-сайта начинается не с редких уязвимостей, а с простых вещей: доступы, формы, загрузка файлов, права на директории, обновления и резервные копии. Большинство неприятных инцидентов происходит не из-за сложной атаки, а из-за оставленного пароля, старой админки или загрузки PHP-файла через форму.
Доступы и пароли
Сначала стоит проверить, кто имеет доступ к серверу, админке, базе данных, панели хостинга и почте домена. Если проект долго поддерживали разные люди, список доступов может быть неожиданным.
- удалить неактуальные учётные записи;
- заменить общие пароли на персональные доступы;
- включить двухфакторную защиту там, где она есть;
- не хранить пароли в репозитории;
- разделить доступы к production и test.
В проекте на Yii2 локальные параметры обычно лежат в config/params-local.php или похожих файлах. Такие файлы не должны попадать в git.
git status
git grep "password"
git grep "secret"
Права на файлы и директории
Права 777 часто ставят “чтобы заработало”. Временно это действительно может помочь, но на рабочем сайте лучше настроить владельца и группы нормально. На запись обычно нужны runtime, web/assets и директории загрузок.
find . -type d -perm 0777
find . -type f -perm 0777
Для большинства проектов достаточно, чтобы веб-сервер мог писать только туда, где это нужно. Конфиги и PHP-код не должны быть доступны на запись всем подряд.
Загрузка файлов
Формы загрузки — одно из первых мест, которое нужно проверить. Нельзя доверять только расширению файла из имени. Нужно проверять MIME-тип, размер, расширение, а загруженные файлы лучше хранить так, чтобы они не выполнялись как PHP.
$file = UploadedFile::getInstance($model, 'file');
if ($file && !in_array($file->extension, ['jpg', 'jpeg', 'png', 'webp'], true)) {
throw new BadRequestHttpException('Недопустимый тип файла');
}
Если загрузки лежат в публичной директории, для неё можно запретить выполнение PHP на уровне nginx.
location /uploads/ {
location ~ \.php$ {
deny all;
}
}
Формы и CSRF
В Yii2 CSRF-защита обычно включена по умолчанию. Проблемы начинаются, когда её отключают для быстрого исправления AJAX-формы и забывают вернуть. Отключение CSRF должно быть редким исключением, а не стандартным решением.
public $enableCsrfValidation = true;
Для AJAX-запросов лучше корректно передавать CSRF-токен, а не выключать проверку целиком.
<meta name="csrf-token" content="<?= Yii::$app->request->csrfToken ?>">
SQL и ActiveRecord
Даже если проект использует ActiveRecord, в старом коде могут оставаться ручные SQL-строки. Опасное место — подстановка данных пользователя прямо в запрос.
// плохо
$sql = "SELECT * FROM users WHERE email = '" . $_GET['email'] . "'";
Нормальный вариант — параметры:
$user = Yii::$app->db->createCommand(
'SELECT * FROM users WHERE email = :email',
[':email' => $email]
)->queryOne();
Админка и служебные разделы
Админка не должна быть доступна без авторизации, а старые служебные файлы лучше удалить. На проектах после переездов часто остаются backup.zip, old.php, test.php, phpinfo.php и временные дампы базы.
find web -iname "*backup*"
find web -iname "*old*"
find web -iname "phpinfo.php"
find web -iname "*.sql"
find web -iname "*.zip"
Если такие файлы нужны для истории, им не место в публичной директории сайта.
Обновления зависимостей
Слепо обновлять все пакеты на рабочем проекте не стоит, особенно если код старый. Но и годами не обновлять зависимости опасно. Хороший вариант — периодически смотреть список устаревших пакетов и обновлять их через тестовый стенд.
composer outdated
composer audit
Если composer audit показывает уязвимость, нужно оценить, используется ли затронутый пакет и доступен ли безопасный апдейт. Иногда обновление требует правок кода, и это лучше планировать отдельно.
Резервные копии
Без резервных копий безопасность неполная. Важно не только создавать бэкапы, но и проверять восстановление. Архив, который никогда не пробовали развернуть, даёт ложное спокойствие.
- бэкап базы выполняется регулярно;
- файлы загрузок сохраняются отдельно;
- копии не лежат только на том же сервере;
- проверено восстановление на тестовом окружении;
- старые копии удаляются по понятному правилу.
Короткий чек-лист
- Проверить актуальные доступы.
- Убрать секреты из репозитория.
- Проверить права 777.
- Запретить выполнение PHP в uploads.
- Проверить CSRF на формах.
- Найти ручные SQL-запросы с подстановкой строк.
- Удалить временные файлы из web.
- Проверить composer audit.
- Проверить наличие и восстановление бэкапов.
Эта проверка не закрывает все вопросы безопасности, но быстро убирает самые частые слабые места. Для большинства небольших PHP-сайтов именно такие базовые вещи дают основной практический эффект.
Комментарии (0)
Пока нет комментариев. Будьте первым!