Перейти к содержимому
>_ITDITDПлатформа веб-безопасности

По фреймворкам

Безопасность Laravel — справочник по продакшн-харденингу

Справочник по продакшн-харденингу Laravel: чек-лист по приоритетам, опасные значения по умолчанию, рекомендации по областям — от секретов и конфигурации до авторизации и CVE зависимостей, плюс чек-лист самопроверки. Защитно, без шагов атаки.

Опубликовано 2026-07-02 Обновлено 2026-07-02 8 мин чтения

Для: всех, кто ведёт Laravel в продакшне. Здесь нет шагов атаки — это рабочий справочник по харденингу: чек-лист по приоритетам, опасные значения по умолчанию, рекомендации по областям и самопроверка. Полную картину по фреймворкам смотрите на хабе безопасности по фреймворкам.

Чек-лист харденинга по приоритетам

Проходите таблицу сверху вниз. P0 — предпосылка для остального, P1 — самый частый источник инцидентов, P2 — постоянная эксплуатационная гигиена.

P0 ── Предпосылка (сначала это)

Отладка выключена в проде / секреты вне публичной поверхности с правами 600 / управление APP_KEY

P1 ── Главный источник инцидентов

Авторизация (Policy/Gate) / контроль Mass Assignment / CVE зависимостей / продакшн-кеширование

P2 ── Эксплуатационная гигиена

Сессии/CSRF/cookie / валидация загрузок / HTTPS, заголовки, ограничение частоты

Укрепляйте от фундамента вверх: P0 (предпосылка) → P1 (главный источник инцидентов) → P2 (эксплуатационная гигиена).
ПриоритетМераКонкретика (Laravel)
P0Отключить отладку в продеAPP_DEBUG=false / APP_ENV=production, закреплено через config:cache. Не раскрывать внутренности на странице ошибки
P0Секреты вне публичной поверхности.env, резервные копии, ключи вне public/, права 600. storage/logs не публичны
P0Безопасно управлять APP_KEYЛежит в основе шифрования, подписанных cookie, сессий. Внедряйте из окружения; ротация при утечке
P1Явная авторизацияPolicy / Gate + authorize() / middleware can, с областью по владельцу/праву
P1Контроль Mass AssignmentОбъявляйте $fillable; избегайте массового присваивания $request->all(), используйте validated()
P1Мониторинг CVE Composercomposer audit / osv-scanner; судите по работающей версии, быстро патчите
P1Продакшн-кешированиеconfig:cache route:cache view:cache для надёжных настроек + скорости
P2Безопасность сессий/cookieЗадайте secure http_only same_site; регенерируйте сессию при входе
P2Валидация загрузокПроверяйте тип/размер, храните вне public/, без права на исполнение
P2HTTPS/заголовки/ограничение частотыПринудительный HTTPS, HSTS, throttle на вход/API

1. Секреты и APP_KEY (P0)

Laravel по умолчанию держит .env вне корня документов (в корне проекта). Инциденты в основном приходят из размещения секретов там, где им не место.

  • Никогда не кладите .env, дампы БД, резервные копии или файлы ключей в public/. Держите секреты вне корня приложения с правами 600 (только владелец).
  • Не выставляйте storage/ или storage/logs/ (логи могут содержать секреты или персональные данные). Не коммитьте .env в репозиторий.
  • APP_KEY лежит в основе шифрования, подписанных URL, шифрованных cookie и сессий. Внедряйте его из окружения и своевременно ротируйте при утечке (учтите, что это делает недействительными существующие шифрованные данные/сессии).

Общий принцип см. в держите секреты вне публичных каталогов; реальный кейс полной открытости — в полная открытость .env.

2. Продакшн-конфигурация: DEBUG, окружение, кеширование (P0)

1

APP_DEBUG=false / APP_ENV=production

Отключите отладку в продакшне. При включённой странице ошибки утекают переменные окружения и данные подключения — извлекаемо через намеренные ошибки.
2

Закрепите конфигурацию кешированием

php artisan config:cache (+ route:cache view:cache) делает применение настроек надёжным и ускоряет приложение. Внимание: после config:cache env() вне config/ возвращает null, поэтому обращайтесь к значениям через config('...') в приложении.
3

Не выставляйте диагностические инструменты в проде

Отключите или ограничьте доступ к Telescope / Horizon / Debugbar в продакшне. Держите подробные ошибки и стек вызовов вне публичной поверхности.

3. Авторизация: Broken Access Control (P1 — главный источник)

Самый частый продакшн-инцидент — «аутентифицирован, но не авторизован». Возможность войти не означает разрешения на действие.

Частое (опасное)

  • нет авторизации — «залогинен = можно смотреть/обновлять»
  • route-model binding достаёт ID другого пользователя
  • Model::create($request->all()) принимает каждое поле
  • поле привилегии вроде is_admin присвоено из пользовательского ввода

Правильно

  • Policy / Gate + authorize() / middleware can, каждый раз ограничивая по владельцу/праву
  • чтения тоже ограничены по владельцу (напр. where('user_id', $me))
  • ограничивайте ввод через $request->validated() (FormRequest)
  • объявляйте $fillable, чтобы блокировать Mass Assignment

См. что такое IDOR. Ключ — проверка владения на каждом пути чтения/обновления/удаления.

4. Инъекции и вывод

Eloquent / построитель запросов Laravel привязывает значения через плейсхолдеры, а Blade по умолчанию экранирует вывод. Правило — не отключайте эту защиту сами.

  • SQL: не подмешивайте пользовательский ввод в whereRaw / DB::raw конкатенацией строк. Даже когда нужен сырой SQL, используйте привязки (→ что такое SQL-инъекция).
  • XSS: Blade {{ }} экранирует; {!! !!} — это сырой вывод. Не передавайте пользовательский ввод в {!! !!}. Если вывести HTML обязательно — только после санитизации (→ что такое XSS).
  • Валидация: проверяйте тип/диапазон/допустимые значения через FormRequest / validate() перед использованием.
  • CSRF: не отключайте глобально защиту CSRF в web-middleware. Используйте @csrf в формах и корректную работу с токенами для SPA (→ что такое CSRF).
  • Cookie/сессии: задайте secure (HTTPS), http_only, same_site в config/session.php. Регенерируйте сессию при входе, чтобы предотвратить фиксацию (аутентификация Laravel регенерирует).
  • Перебор: применяйте throttle / лимиты попыток входа к логину.

6. Загрузка файлов и публичные файлы (P2)

  • Проверяйте mime-тип, расширение и размер, и не доверяйте имени файла, присланному клиентом.
  • Храните вне public/ (напр. storage/) без права на исполнение. Отдавайте наружу только необходимое, через контролируемый путь.
  • Ставьте авторизацию и на выдачу, чтобы последовательные прямые ссылки не доставали файл другого пользователя.

7. HTTPS, заголовки безопасности, ограничение частоты (P2)

  • Принудительный HTTPS (URL::forceScheme('https') и т. п.) + HSTS. За балансировщиком нагрузки используйте TrustProxies, чтобы схема определялась корректно.
  • Заголовки безопасности (X-Content-Type-Options и т. п.; проектируйте CSP под вашу схему ассетов). Проверьте свой сайт с помощью проверки заголовков безопасности.
  • Ограничение частоты: применяйте throttle к входу, API и сбросу пароля.

8. Зависимости и версии (P1)

Проверка: ваш Laravel действительно укреплён?

Собрать — это не конец; готово только после того, как вы проверили. Это защитные самопроверки против вашего собственного сайта/окружения.

1

Секреты недостижимы по URL

На своём домене обратитесь к /.env и /storage/logs/laravel.log и убедитесь, что они возвращают 404 (если достижимы — немедленно исправьте и ротируйте ключи).
2

Нет открытой отладки в проде

Вызовите ошибку (напр. несуществующий маршрут) и убедитесь, что показывается обобщённая страница ошибки — без переменных окружения и стека вызовов.
3

Авторизация держится

В тестовом окружении запросите ID ресурса другого пользователя и убедитесь, что отказано (на путях чтения, обновления и удаления).
4

Cookie/сессии и зависимости

Убедитесь, что cookie сессии несёт Secure/HttpOnly/SameSite, и что composer audit чист.

Взгляд этого сайта: даже при сильных значениях по умолчанию авторизация и зависимости — на вас

У Laravel много хороших значений по умолчанию, но авторизация — кто и что может делать — и свежесть зависимостей специфичны для приложения и эксплуатации, поэтому ни один фреймворк не защитит их автоматически. Инциденты, которые мы видим снова и снова, — не столько изощрённые атаки, сколько типы настроек/эксплуатации: «аутентифицирован, но нет проверки владения», «отладка открыта в проде», «секрет раскрыт». Поэтому центр тяжести — проработка таблицы выше сверху вниз и неброская работа: ограничивайте каждое чтение/обновление по владельцу и мониторьте зависимости на CVE.

Читать дальше

FAQ

QЧто нужно сделать в первую очередь, чтобы защитить Laravel?
A

Три пункта P0: (1) убедитесь, что APP_DEBUG=false в продакшне, и закрепите конфигурацию через config:cache; (2) держите .env и файлы секретов вне публичного каталога с жёсткими правами; (3) безопасно управляйте APP_KEY (он лежит в основе шифрования, подписанных cookie и сессий, так что при утечке — ротация). Это предпосылки для всего остального. Дальше переходите к авторизации (Policy/Gate) и мониторингу CVE зависимостей Composer.

QЧем опасно выкатить с APP_DEBUG=true?
A

При включённой отладке страница ошибки может показать не только стек вызовов, но и внутренние данные вроде значений конфигурации, переменных окружения и данных подключения. Атакующий может намеренно вызывать ошибки, чтобы их извлечь. В продакшне ставьте APP_DEBUG=false и APP_ENV=production и закрепляйте это через config:cache. Также не выставляйте наружу диагностические инструменты вроде Telescope или Debugbar в продакшне.

QПочему env() возвращает null после config:cache?
A

config:cache компилирует вашу конфигурацию в один файл для скорости, и после этого env(), вызванный вне файлов конфигурации, возвращает null (читается только .env на момент кеширования). Решение — использовать env() только внутри config/ и обращаться к значениям в приложении через config('...'). В продакшне кеширование config/route/view — норма: настройки применяются надёжно, а приложение ускоряется.

QКак не допустить «залогинен — значит, можно»?
A

Аутентификация (вход) и авторизация (можно ли выполнить действие) — разные вещи. В Laravel реализуйте Policy/Gate и используйте authorize() или middleware can, чтобы ограничивать каждое чтение/обновление/удаление по владельцу или праву. Также контролируйте Mass Assignment, объявляя $fillable, и избегайте массового присваивания $request->all(). Без этого подмена ID в URL достаёт данные другого пользователя (IDOR).

QКак управлять уязвимостями зависимостей Composer?
A

Мониторьте известные CVE машинно через composer audit или osv-scanner, судите по работающей версии и быстро патчите (решение по тому, что реально установлено, а не по объявлению в composer.json). Также держите Laravel и PHP на поддерживаемых версиях и не оставляйте EOL-версии. Свежесть зависимостей — более реалистичный фактор инцидентов, чем изощрённые атаки.