Перейти к основному содержимому
Версия: 5.x

Безопасность

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

Чек-лист​

  • Обслуживайте эндпоинт только через WSS.
  • Ограничьте origin'ы, если используете cookie.
  • Не передавайте токены в URL или используйте короткоживущие тикеты.
  • Реализуйте аутентификатор, который проверяет токены; аутентификатор по умолчанию доверяет только HTTP-идентичности.
  • Проверяйте доменные права доступа в действиях или фильтрах.
  • Самостоятельно обеспечивайте истечение и отзыв сессий.
  • Ограничивайте число соединений на пользователя или IP на уровне хоста или прокси.
  • Изолируйте Redis сетевыми правилами и ACL.
  • Маскируйте токены и payload в логах.

Межсайтовый перехват WebSocket​

CORS не действует на WebSocket. При аутентификации через cookie страница на другом сайте может открыть сокет к вашему эндпоинту; браузер приложит cookie пользователя, и сокет станет DarkWS-сессией этого пользователя.

Ограничьте origin'ы:

app.UseWebSockets(new WebSocketOptions { AllowedOrigins = { "https://app.example.com" } });

Другие origin'ы получают 403 ещё до того, как DarkWS их аутентифицирует. Запросы без заголовка Origin (небраузерные клиенты) по-прежнему принимаются. Пустой список — значение по умолчанию для UseWebSockets() — разрешает любые origin'ы.

Если другим WebSocket-эндпоинтам приложения нужны другие origin'ы, задайте вместо этого DarkWsOptions.AllowedOrigins. Этот параметр применяется только к эндпоинту DarkWS, сравнивается без учёта регистра и проверяется до запуска аутентификатора.

Токены в URL​

Токены в URL WebSocket могут попасть в логи прокси, логи доступа и телеметрию.

  • Предпочитайте передавать в URL короткоживущий одноразовый тикет подключения.
  • Либо, если ваш эндпоинт допускает анонимный upgrade, оставьте URL чистым и аутентифицируйтесь через сокет с помощью authenticationToken (браузер) или AuthenticationTokenProvider (.NET). Тогда каждый сокет проходит аутентификацию до отправки защищённых запросов.
  • Маскируйте учётные данные при логировании URL и сообщений. См. рекомендации ASP.NET Core по логированию токенов доступа.

Попытки аутентификации​

DarkWS не ограничивает попытки auth:: одно соединение может перебирать токены так быстро, как позволяет сеть, и каждая попытка запускает ваш аутентификатор.

  • Используйте токены с высокой энтропией.
  • Если тикеты короткие или проверка дорогая, считайте неудачи в аутентификаторе (по ключу HttpContext.Connection.Id, пользователя или IP клиента) и вызывайте HttpContext.Abort(), чтобы разорвать соединение по достижении лимита.

Время жизни сессии​

Истечение срока действия или отзыв токена не закрывает существующее соединение. Сокет может оставаться открытым несколько дней.

  • Храните срок действия в своей сессии и проверяйте его в фильтре действий.
  • При отзыве найдите соединения через IDarkWsConnections.GetBySession(id) и закройте их.
  • KeepSessionOnFailedAuthentication сохраняет старую сессию после неудачного обновления; включайте его, только если срок действия проверяется в другом месте.
  • Клиенты не хранят токены, переданные вручную. После logout очистите источник токенов приложения, чтобы переподключение не восстановило старые учётные данные.

Авторизация​

Обработчикам нужна сессия, если они не помечены [AllowAnonymous]. Встроенной авторизации по ролям или политикам нет: [Authorize] приводит к ошибке регистрации, чтобы его нельзя было молча проигнорировать. Проверяйте права в действиях или в фильтрах действий и возвращайте контролируемые ошибки через ErrorResponseException.

Лимиты ресурсов​

Для каждого соединения DarkWS ограничивает размер сообщения (MaxMessageSizeBytes, 1 MiB), число параллельных запросов (16), запросов в очереди и время отправки. См. Конфигурация и лимиты. DarkWS не ограничивает:

  • число соединений: используйте хост (лимиты Kestrel) или обратный прокси;
  • частоту запросов на пользователя или IP: используйте rate limiting в хосте или фильтр действий;
  • размер сообщений Redis: ограничивайте то, что отправляют ваши издатели.

Redis​

Любой, кто может публиковать в канал backplane, может отправлять уведомления всем клиентам. Ограничьте доступ сетевой изоляцией и ACL Redis. Номера логических баз данных не изолируют Pub/Sub. См. Redis backplane.

Подробности ошибок​

Непредвиденные исключения логируются, а в ответ отправляется darkws:error:request-failed; их сообщения никогда не доходят до клиентов. Отправляются только данные, которые вы передаёте в Error(code, details) или ErrorResponseException<T>.

Сообщение об уязвимости​

Не открывайте публичный issue. Сообщите приватно через GitHub Security Advisories, указав затронутый пакет и версию, последствия и шаги воспроизведения. Исправления выпускаются для последней мажорной версии.