Middleware не являются чем-то новым. Мы уже давно используем их в web приложениях для различных целей, от аутентификации до авторизации и не только.
В этом руководстве речь пойдет о том, как можно использовать возможности middleware в приложении на Laravel, чтобы повысить их безопасность. Вы можете добавить в свое приложение бесчисленное количество headers, которые выполняют разные функции. Давайте углубимся в несколько разных заголовков безопасности, чтобы увидеть, что они делают — и что мне как разработчику, нравится делать в моих приложениях.
Первое, что мы хотим сделать, думая о безопасности в нашем приложении на Laravel, — подумать о headers, которые не хотим раскрывать. Как правило, приложение по умолчанию отображает следующие headers:
X-Powered-By — отображает технический стек, на котором работает приложение.
server/Server — отображает серверную технологию, на которой работает приложение. Например, apache или nginx и т. д.
Первое, что мы сделаем,- это удалим эти заголовки.
Я работаю в компании Treblele, которая похожа на Google Analytics для вашего API. Скоро мы выпустим новую проверку безопасности API, и поэтому мной открыт доступ к исходному коду с использованием middleware, который применяется нами для скрытия определенных headers. Выглядит это следующим образом:
final class RemoveHeaders
{
public function handle(Request $request, Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);
/**
* @var string $header
*/
foreach ((array) config('headers.remove') as $header) {
$response->headers->remove(
key: $header,
);
}
return $response;
}
}
Этот middleware просматривает настроенные headers в моем файле конфигурации и гарантирует, что они будут удалены из ответа, прежде чем вернуть его пользователю.
Следующее, что я обычно делаю, это устанавливаю для заголовка Referrer-Policy значение no-referrer-when-downgrade, когда запрос возвращается к тому же источнику, но не для любых запросов между источниками. Я делаю это с помощью другого middleware:
final class SetReferrerPolicy
{
public function handle(Request $request, Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);
$response->headers->set(
key: 'Referrer-Policy',
values: config('headers.referrer-policy),
);
return $response;
}
}
Разделяя эти действия на отдельные middleware, можно конкретно указать уровень, который важен для меня в отношении безопасности на каждом маршруте. Таким образом мы можем быть более открытыми для одних маршрутов и менее открытыми для других.
Давайте немного поговорим о заголовке Strict-Transport-Security. Данный header сообщит клиенту/браузеру о необходимости подключения к приложению с помощью HTTPS и о том, как долго должно действовать это правило. Этот header помогает защитить пользователей вашего приложения от атаки “человек посередине” (man-in-the-middle attacks). Вы также можете добавить в этот заголовок includeSubdomains, чтобы указать браузеру применить policy ко всем поддоменам веб-сайта.
final class StrictTransportSecurity
{
public function handle(Request $request, \Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);
$response->headers->set(
key: 'Strict-Transport-Security',
values: config('headers.strict-transport-security'),
);
return $response;
}
}
Следующий header, на который мне бы хотелось обратить внимание, это Content-Security-Policy header, как один из наиболее часто используемых. Я не создавал специальный middleware для этого, так как у Spatie есть отличный пакет Laravel-csp, который вы можете использовать. В связанной статье новостей Laravel есть отличные инструкции о том, как настроить Laravel-csp, поэтому в данной статье я не буду вдаваться в подробности. Итак, давайте двигаться дальше.
Используемый вами SSL-сертификат может иметь разные уровни прозрачности для ваших пользователей. Этот общедоступный механизм регистрации позволит любому контролировать выдачу сертификата, что в свою очередь, поможет обнаруживать и предотвращать такие вещи, как поддельные сертификаты. Сертификат также имеет различные параметры конфигурации:
`max-age` - максимальное время (в секундах), в течение которого браузер должен помнить policy.
`enforce` - укажет, хотите ли вы, чтобы браузер применял policy. Если мы установим для этого параметра значение true, браузер не будет разрешать подключения без SSL к вашему приложению.
`report-uri` - укажет URL-адрес, по которому браузер должен отправлять любые отчеты о нарушениях соблюдения политики доверия CT policy (Certificate Transparency policy) вашего приложения.
Давайте посмотрим на middleware для этого и что необходимо сделать:
final class CertificateTransparencyPolicy
{
public function handle(Request $request, \Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);
$response->headers->set(
key: 'Expect-CT',
values: config('headers.certificate-transparency'),
);
return $response;
}
}
Как видите, некоторые из этих классов middleware просты. Их комбинация даст наилучшую защиту от потенциальных атак.
Последний middleware, который мы рассмотрим, — это заголовок Permissions-Policy. Данный header можно использовать, чтобы сообщить браузеру, какие функции и API разрешено использовать браузеру. Это поможет защитить вас от таких вещей, как XSS-атаки и кликджекинг.
final class PermissionsPolicy
{
public function handle(Request $request, \Closure $next): Response
{
/**
* @var Response $response
*/
$response = $next($request);
$response->headers->set(
key: 'Permissions-Policy',
values: config('headers.permissions-policy'),
);
return $response;
}
}
Используя этот middleware, я могу точно определить features, которые хочу включить и обеспечить большею безопасность для своего конечного пользователя и себя.
Еще один замечательный пакет, который вы можете проверить, — это Laravel Security Headers от Роба Фонсека.
Используете ли вы какие-либо middleware? Или, может быть, конкретная настройка для одного из перечисленных? Сообщите нам!
Оригинал статьи: https://laravel-news.com/laravel-security-middleware