Вы только что развернули свое приложение Laravel. Миграции выполняются, кэши очищаются, а для APP_DEBUG  устанавливается значение  false   . Вы чувствуете себя в безопасности. Но вот неприятная правда: каркас защищает вас только до тех пор, пока вы сами не откроете дверь. Самые смелые эксплойты не живут в ядре — они живут в бизнес-логике, которую вы написали в прошлую пятницу в рамках крайнего срока.
Давайте пройдемся по десяти реальным слабым местам в приложениях Laravel не как скучному контрольному списку, а так, как их видит злоумышленник — с механикой, примерами и хакерским взглядом на элегантность.

1. Массовое присвоение: когда ваша модель доверяет всему

 Проблема
Вы используете User::create($request->all()) , а злоумышленник подставляет is_admin: true  в полезные данные запроса. Красноречивый послушно все сохраняет.

 Схема атаки 

dOhjStYFmulfEHWfqQ6XUhnwOSFVY61Csb09ptmy.png

 Исправление
Всегда определяйте $fillable  или $guarded  . Никогда не передавайте нефильтрованные входные данные:

protected $fillable = ['name', 'email'];

// or

protected $guarded = ['is_admin', 'role', 'balance'];

$user->fill($request->only(['name', 'email']));


2. Утечка информации через режим отладки

The problem
You forgot APP_DEBUG=true  on production. A 500 error spills stack traces, file paths, package versions, and environment variables. For an attacker, it’s like finding the blueprint of your house.

 Визуальный 

AUkTsvZRpUVIIqBhx4vHvQVpgD7DOnw7tn4nKvUi.png

 Исправление 

APP_DEBUG=false
APP_ENV=production

Ошибки передаются в Sentry, Flare или ELK. Не показывайте пользователям ничего, кроме дружественной страницы с ошибкой.


3. SQL-инъекция: когда необработанные запросы кусаются

 Проблема
Объединение пользовательского ввода в SQL или неправильное использование DB::raw()  мгновенно отменяет всю защиту Laravel.

 Код уязвимости 

$user = DB::select("SELECT * FROM users WHERE email = '$email'");

Ввод ' OR 1=1 --  возвращает всю таблицу.

 Безопасный подход 

DB::table('users')->where('email', $email)->first();

// or parameterized

DB::select('SELECT * FROM users WHERE email = ?', [$email]);

Даже ->orderByRaw()  должен использовать заполнители, а не интерполяцию.


4. Небезопасная десериализация: объекты-зомби

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

 Концепция цепочки атак 

YSsD0RQFrXVYBwFsXGam6fsUYxPXNvqgA1lu53A6.png

 Усиление 

  • Никогда unserialize()  данные, которые вы не создали.
  • Переключите очереди и кеш на сериализацию JSON.
  • Ограничить разрешенные классы в полезных нагрузках задания.
  • Избегайте  'serialize'   в качестве драйвера сеанса.


5. CSRF и SPA: когда защита отключается «для удобства»

 Проблема
Глобальное удаление VerifyCsrfToken  или неправильная настройка Sanctum для SPA оставляет конечные точки, меняющие состояние, открытыми для подделки межсайтовых запросов.

 Исправление 

  • Никогда не отключайте глобальное промежуточное программное обеспечение CSRF; исключить только определенные маршруты веб-перехватчиков.
  • Для API, используемых мобильными и собственными приложениями, используйте аутентификацию на основе токенов (токены Sanctum API, Passport).
  • Для SPA в одном домене используйте режим cookie Sanctum и сохраните same_site: lax  .


6. Перехват сеанса и перебор: решето для входа в систему

 Проблема
Файлы cookie без флагов HttpOnly  и  Secure   крадут через XSS или MitM. Без ограничения скорости злоумышленники могут свободно подбирать пароли.

 Глубокоэшелонированная защита 

SESSION_SECURE_COOKIE=true
SESSION_HTTPONLY=true
SESSION_SAME_SITE=lax

Добавьте ограничитель скорости входа:

RateLimiter::for('login', fn (Request $request) =>
    Limit::perMinute(5)->by($request->input('email').$request->ip())
);

Всегда хэшируйте пароли с помощью Hash::make()  (bcrypt/argon2) и включайте двухфакторную аутентификацию (Laravel Fortify).


7. XSS: когда Blade не может тебя спасти

 Проблема
 {!! $comment !!}  выводит необработанный HTML. Злоумышленник вводит <script>steal(document.cookie)</script>  .

 Безопасный выход 

{{ $comment }}  <!-- auto-escaped -->

Если вам необходимо визуализировать HTML, очистите его с помощью HTMLPurifier и соблюдайте строгую политику безопасности контента:

Content-Security-Policy: default-src 'self'


8. IDOR: доступ к заказам других людей

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

 Поток 

Ier5caNMKtpJPNjZBsnXz9HIlC5GJRIzBqvgA8yc.png

 Исправление
Всегда ограничивайте запросы только аутентифицированным пользователем:

$order = Order::where('user_id', Auth::id())->findOrFail($id);

// plus Policy
$this->authorize('view', $order);


9. Открытые перенаправления: «Переслать меня куда угодно»

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

 Опасно 

return redirect()->away($request->input('to'));

 Сейф 

return redirect()->to('/dashboard');

Если необходимы динамические перенаправления, проверьте белый список разрешенных доменов. Используйте intended()  с правильной фильтрацией.


10. Зависимости зомби: бомба замедленного действия

 Проблема
Вы получаете пакет для крошечной функции, забываете о нем, а год спустя у него появляется критический CVE — а ваш  композитор.lock   все еще закрепляет уязвимую версию.

 Периодичность обслуживания 

  • Запустите проверку  композитора   в CI.
  • Включите GitHub Dependabot или Snyk.
  • Удалить неиспользуемые пакеты; каждая дополнительная зависимость — это потенциальная дверь.


Практический контрольный список аудита

Перед каждым выпуском проверяйте:

  •  Среда : установлены APP_DEBUG=false  , APP_KEY , в коде нет тестовых секретов.
  •  Модели : правильный $fillable  / $guarded  .
  •  База данных : нулевой необработанный SQL со строковой интерполяцией.
  •  Auth : ограничение скорости, 2FA, безопасные флаги cookie.
  •  Авторизация : Политики/шлюзы повсюду.
  •  Интерфейс : экранирование лезвий, заголовки CSP, фильтрация HTML.
  •  Ошибки : в ответах нет трассировки стека.
  •  Перенаправления : только безопасные внутренние пути.
  •  Зависимости :  аудит композитора   очищен, пакеты обновлены.
  •  Автоматизация : PHPStan/Larastan на CI, периодическое сканирование SAST/DAST, базовые пентесты.

Последнее слово

Безопасность Laravel — это не волшебный флаг в вашем .env   — это дисциплина. Самые впечатляющие нарушения происходят не из-за нулевых дней в ядре; они происходят из небрежной бизнес-логики. Изучите механику, проведите внутренний аудит с мышлением  «а что, если я злоумышленник?» , и вы не допустите настоящих плохих парней.