Middleware обеспечивающее безопасность Laravel
В этом руководстве я расскажу, как можно использовать middleware в приложении Laravel для повышения безопасности. Вы можете добавить в приложение бесчисленное количество заголовков делающих разные вещи. Давайте рассмотрим несколько заголовков, чтобы увидеть, что они делают, и что я люблю делать в своих приложениях.
Первое, что мы хотим сделать, думая о безопасности в Laravel приложении — подумать о заголовках, которые мы не хотим раскрывать. Обычно приложение по умолчанию отображает следующие заголовки:
X-Powered-By
— отображает технический стек вашего приложения.server
/Server
— отображает серверную технологию, на которой работает приложение. Например,apache
илиnginx
и т.д.
Первое, что мы хотим сделать — удалить эти заголовки.
Я работаю в компании Treblete, которая похожа на Google Analytics для вашего API. Скоро мы выпустим новую проверку API Security, и у меня есть middleware с открытым исходным кодом, которое мы используем для скрытия определённых заголовков. Это выглядит следующим образом:
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 просматривает настроенные заголовки в файле конфигурации и гарантирует, что они будут удалены из ответа, прежде чем он вернётся пользователю.
Следующее, что я делаю — устанавливаю для заголовка 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
. Он сообщает клиенту/браузеру о необходимости подключения к приложению с помощью HTTPS и о том, как долго должно действовать это правило. Заголовок помогает защитить пользователей приложения от атак man-in-the-middle
. Вы также можете добавить в этот заголовок includeSubdomains
, чтобы указать браузеры применить эту политику ко всем поддоменам веб-сайта.
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;
}
}
Следующий заголовок, который мне нравится, это Content-Security-Policy
, один из наиболее часто используемых. Я не писал специальное middleware для него, так как у Spatie есть фантастический пакет, который вы можете использовать. В статье по ссылке есть отличные инструкции о том, как это настроить, поэтому не буду вдаваться в подробности. Давайте двигаться дальше.
Ваш SSL-сертификат может иметь разные уровни прозрачности для пользователей. Это публичный механизм ведения логов позволит любому отслеживать выдачу сертификатов. Это помогает обнаруживать и предотвращать такие вещи, как поддельные сертификаты. Он также имеет различные параметры конфигурации:
max-age
указывает максимальное время (в секундах), в течении которого браузер должен помнить политику.enforce
указывает, хотите ли вы, чтобы браузер применял политику. Если для этого параметра установить значениеtrue
, браузер не будет разрешать подключения без SSL к вашему приложению.report-uri
указывает URL-адрес, по которому браузер должен отправлять любые отчёты о нарушениях CT политики вашего приложения.
Давайте рассмотрим 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
. Мы можем использовать этот заголовок, чтобы сообщить, какие возможности и функции 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, я могу точно определить функции, которые хочу включить, а это означает, что я могу обеспечить большую безопасность для конечного пользователя и для себя.
Используете какое-то дополнительное middleware? Или, может быть, специфичные настройки для одного из перечисленных? Дайте нам знать!