12 лучших практик безопасности Laravel на 2023 год

Источник: «12 Laravel security best practices for 2023»
Обеспечение безопасности приложения Laravel: защита конфиденциальных файлов, обновление пакетов и Laravel, использование политик, проверка вводимых данных и многое другое.

Безопасность — обширная тема, и данная статья не охватывает её полностью. Да и возможно ли это вообще?

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

Не отслеживайте .env-файл

Ваш .env-файл содержит конфиденциальную информацию.

Пожалуйста, не отслеживайте его!

Убедитесь, что он добавлен в .gitignore.

Чаще всего утечки данных происходят внутри компании.

Менеджер паролей — лучшее решение для обмена учётными данными.

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

Поддерживайте Laravel в актуальном состоянии

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

Убедитесь, что используете версию Laravel, для которой все ещё выпускаются исправления, и все будет в порядке.

Если вы никогда не обновляли проект Laravel, прочитайте Laravel 10: Руководство по обновлению, которое подскажет вам, как это сделать.

Поддерживайте в актуальном состоянии базовые и сторонние пакеты

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

Но чем больше пакетов вы используете, тем больше точек отказа может возникнуть.

Регулярное выполнение composer update значительно повышает безопасность кодовой базы.

Отключите отладочные сообщения в production

Убедитесь, что эти две переменные окружения корректно установлены в production.

APP_ENV=production
APP_DEBUG=false

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

Не передавайте конфиденциальную информацию средствам мониторинга ошибок

Если говорить о конфиденциальной информации в отладочных сообщениях, то мы ещё не избавились от неё.

Если вы используете инструмент мониторинга ошибок, то они должны быть и там.

В PHP 8.2 появился новый атрибут #SensitiveParameter, позволяющий скрыть любую информацию из трассировки стека (которая отправляется в средства мониторинга ошибок).

function something(
#[\SensitiveParameter]
$top_secret_parameter,
$who_cares_parameter,
) {
throw new \Exception('Whoops, something bad happended!');
}

Ограничение частей приложения с помощью политик

Политики в Laravel — это как вышибалы в ночном клубе, препятствующие доступу людей в запрещённые зоны.

Давайте рассмотрим реальный пример использования политики:

// app/Policies/PostPolicy.php
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}

// app/Http/Controllers/PostController.php
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);

// ...
}

Как видите, с их помощью очень легко проверить наличие разрешения, прежде чем разрешить пользователю что-либо делать.

Обязательно ознакомьтесь с документацией, поскольку о политиках можно многое узнать.

Защита форм от подделки межсайтовых запросов (CSRF)

Возможно, вам захочется использовать в своих формах директиву @csrf Blade.

<form method="POST" action="{{ route('register') }}">
@csrf

<p>
<label for="name">First Name</label>
<input type="text" id="name" name="name" value="{{ old('name') }}" required />
</p>


</form>

Данная директива генерирует скрытое поле ввода, содержащее CSRF-токен, автоматически включаемый при отправке формы.

Этот токен подтверждает, что форма отправляется из вашего приложения, а не от третьего лица.

Проверка осуществляется с помощью middleware VerifyCsrfToken, которое Laravel использует по умолчанию для всех ваших веб-маршрутов.

Подробнее о защите от CSRF можно узнать из документации Laravel.

Валидация вводимых пользователем данных

Валидация в Laravel имеет решающее значение для обеспечения безопасности приложения.

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

use Illuminate\Http\Request;

class PostController extends Controller
{
function store(Request $request)
{
$validated = $request->validate([
'user_id' => 'required|exists:users,id',
'title' => 'required|string|min:3|max:255',
'content' => 'required|string|min:3',
'published' => 'sometimes|boolean'
]);

Post::create($validated);

//
}
}

Подробнее о валидации в Laravel можно узнать из официальной документации.

Будьте осторожны с загружаемыми файлами

Как мы уже видели, пользовательскому вводу никогда нельзя доверять. Это относится и к загружаемым файлам. Вот несколько рекомендаций:

  1. Проверьте MIME-тип файла (в Laravel для этого есть соответствующие правила валидации).

    $request->validate([
    'file' => 'required|mimes:gif,jpeg,png,webp',
    ]);
  2. По возможности не делайте загруженные файлы общедоступными (например, с помощью драйвера локального файла).

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

  4. Делегируйте загрузку файлов сторонним сервисам, которые известны своей безопасностью (то есть никогда не допускают утечки данных).

Шифрование полезной нагрузки в заданиях

Когда вы отправляете задание, его полезная нагрузка сохраняется в базе данных, Redis или другой системе, которую вы указали Laravel использовать с помощью переменной окружения QUEUE_DRIVER.

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

К счастью, в Laravel предусмотрен контракт Illuminate\Contracts\Queue\ShouldBeEncrypted, который автоматически шифрует полезную нагрузку. Чтобы убедиться, что никто не сможет их расшифровать, убедитесь, что ключ Laravel APP_KEY, определённый в вашем .env, недоступен никому, кроме нескольких доверенных лиц.

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;

class SomeJob implements ShouldQueue, ShouldBeEncrypted
{
//
}

Пишите тесты для выявления рисков безопасности

К сожалению, тестирование является обширной и малоизвестной темой среди разработчиков.

Автоматическое тестирование нескольких сценариев на предмет потенциальных нарушений безопасности — отличный способ убедиться, что они остаются закрытыми.

Laracasts предлагает бесплатные курсы по тестированию, которые помогут вам начать работу. Один из них посвящён PHPUnit, отраслевому стандарту, а другой — Pest, лучшему фреймворку для тестирования на этой планете, который модернизирует и упрощает тестирование на PHP.

Проводите регулярные аудиты безопасности

Эта практика является одной из самых эффективных и должна быть обязательной для всех, кто серьёзно относится к безопасности. Внешняя обратная связь может открыть глаза.

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

Дополнительные материалы

Предыдущая Статья

Руководство по шифрованию и хэшированию в Laravel

Следующая Статья

Laravel 11: грядущие изменения и дата выхода