Аудит безопасности Laravel CRM: 16 найденных проблем и адресные исправления

В моей практике повторная проверка Laravel CRM показала, почему поверхностного аудита недостаточно. После первых исправлений оставались нарушения границ доступа, проблемы импорта и экспорта, обработки документов и серверного доступа. Ниже — обезличенный кейс с подтверждёнными результатами и остаточными рисками.

85маршрутов проверено
24контроллера
13моделей
16находок повторного аудита
Аудит Laravel CRM: охват проверки и приоритеты 16 находок
Схема выполненной работы; без данных клиентов и деталей доступа.

Задача и охват

Исходный стек: Laravel 12, PHP 8.2, MySQL, Redis и очереди. Мною проверены маршруты, контроллеры, модели, миграции и фактическая схема БД; отдельно — policies/middleware, формы и API, импорты/экспорты, документы, фоновые задачи, зависимости и инфраструктура.

Метод — обнаружить, ограничить scope, проверить доказательства и описать риск. Вывод связывался с фактическим поведением, исходным кодом, схемой БД или конфигурацией; сам перечень потенциально опасных конструкций не считался готовым finding.

Приоритеты повторного аудита

P1 — 8 проблем

Сначала — риски раскрытия данных, небезопасного вывода, потери документов и серверного доступа.

P2 — 6 проблем

Следующий этап — внутренние поля, управление доступом, очередь, конфигурация и эксплуатационная устойчивость.

P3 — 2 проблемы

Плановые исправления воспроизводимости схемы и дублирующих определений.

P0 — 0

На момент этой проверки находок такого приоритета не зафиксировано. Это не гарантия отсутствия неизвестных рисков.

Основные классы проблем и исправления

Разграничение доступа

Связанные записи ограничены владельцем и направлением; ответы минимизированы. Policies и видимый scope защищают работу с заявками и документами.

Массовый импорт

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

Stored XSS и XLSX

Пользовательские данные выводятся безопасно; строки экспорта принудительно сохраняются как текст, а не исполняемые формулы.

Документы и очередь

Неуспешная обработка не считается успехом. Добавлены повторные попытки и сохранение исходника при ошибке.

Секреты и конфигурация

Служебные значения исключены из JSON и сериализуемых заданий; runtime получает конфигурацию на этапе исполнения.

SSH и сеть

Парольный SSH-вход отключён, firewall ограничивает входящий доступ. Согласованное исключение для root key-only зафиксировано отдельно.

Защита документов

Наружу выдаются непрозрачные ссылки со случайным идентификатором. Получение файла требует входа и проверки прав на конкретную заявку; реальные пути и исходные имена хранения не раскрываются.

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

Что подтверждено проверками

  • На первом этапе, до удаления dev-зависимостей: 32 unit-теста и 89 assertions — успешно. Это не полный регрессионный набор для всех последующих 16 находок.
  • Проверка синтаксиса изменённых PHP/Blade-файлов и production Vite build — успешно.
  • На дату соответствующих проверок Composer audit и npm audit не показывали advisories в проверенном составе зависимостей.
  • В целевой runtime-проверке XLSX пользовательская строка записывается как текст.
  • При контролируемой ошибке обработки документа задача попала в failed_jobs, исходный файл сохранён.
  • В повторном read-only проходе production автотесты не запускались: dev-зависимости были удалены; полный authenticated smoke по всем ролям оставался ограничением.

Исправлено и исключено — разные статусы

По таблице повторного отчёта 13 пунктов закрыты, один закрыт с согласованным исключением, два исключены заказчиком. Исправления приложения применены; это отдельная работа от кейса Docker/PHP, где deploy не выполнялся.

  • Исключено заказчиком: очистка секретов и дампов из Git-истории. Удаление из актуального дерева не очищает предыдущие версии.
  • Исключено заказчиком: обновление ОС и системных пакетов. Этот остаточный риск не выдаётся за устранённый.
  • Согласованное исключение: административный root-доступ сохранён только по ключу.
  • Ротация исторических секретов и полная проверка ролей требуют отдельного подтверждения; в этом кейсе они не заявлены завершёнными.

Ограничения и результат

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

Во время одного из этапов установки зависимостей возник кратковременный ответ 500 из-за незавершённой генерации autoload; после завершения установки проверка входа вернула 200. Поэтому этому кейсу не приписывается бесшовный deploy без ошибок.

Публичное описание не содержит маршрутов эксплуатации, данных клиента, адресов сервера и секретов.

Частые вопросы

Все 16 проблем исправлены?

Нет. В отчёте разделены закрытые пункты, согласованное исключение и два исключённых заказчиком направления: Git-история и обновление ОС.

Можно ли ограничиться Composer audit?

Нет. Нарушения границ доступа, импорта, вывода и логики очередей не сводятся к списку известных уязвимостей пакетов.

Услуги, статья и подтверждённые кейсы

Запросить аудит Laravel CRM →Telegram @ifwcom

Давайте обсудим проект

Расскажите, что хотите сделать. Я отвечу на вашу почту.

Или напишите в Telegram @ifwcom