Ray 2.58.0 вышел 23 августа в 05:42 UTC. Среди исправлений Ray Serve в списке изменений есть одна строка: исправление обхода token authentication в экземпляре Serve ASGIService. Ни security advisory не приложено, ни CVE не запрошен, и уровень серьезности не указан.

Что говорит pull request

PR #65189 куда более конкретен, чем changelog. Внутренний gRPC-сервер в экземплярах Serve «был собран с использованием обычного grpc.aio.server() и привязан через add_insecure_port», что, по словам автора, делало его единственным Python-side gRPC-сервером в Ray, который обходил оба транспортных механизма контроля Ray. При RAY_AUTH_MODE=token сервис принимал запросы без действительных учетных данных и доходил до pickle.loads(request.pickled_request_metadata) до любой проверки. При RAY_USE_TLS=1, где другие Python gRPC-серверы Ray используют mTLS, этот порт оставался незашифрованным.

Проблема именно в том, что pickle.loads вызывается до проверки

Десериализация pickle, присланного атакующим, по определению означает произвольное выполнение кода — об этом прямо говорит документация Python. Здесь важен порядок: сначала распаковывался недоверенный payload, а аутентификация выполнялась потом. Это делает аутентификацию на этом пути не просто слабой, а не имеющей значения.

Искажение: не новая уязвимость, а разрыв на пять релизов

В 2.52.0 Ray представил token authentication, описанную как охватывающую все компоненты Ray. Этот порт в нее не входил. Любой, кто включил RAY_AUTH_MODE=token, полагаясь на то замечание о релизе, с тех пор запускал неаутентифицированную точку десериализации на каждом экземпляре Serve. Исправление не добавляет защиту; оно сокращает разрыв между тем, что было задокументировано, и тем, что было на самом деле.

Исправление появилось за восемнадцать дней до релиза

PR #65189 был смержен 5 августа. До операторов он дошел 23 августа, когда вышел 2.58.0. Эти восемнадцать дней патч был доступен для чтения в публичном репозитории, пока ни один релиз его не содержал — обычная цена исправления security issue в открытом коде без эмбарго и причина, по которой строка в changelog важнее, чем кажется по ее месту.

Что должны проверить операторы

Риск зависит от сетевой доступности, поскольку порт привязывается ко всем интерфейсам на эпемерном порту. Важны те кластеры, где экземпляры Serve находятся в сети, доступной недоверенным вызывающим. Обновление переводит и клиент, и сервер на общие gRPC-хелперы Ray, которые применяют interceptors и настройки TLS, уже используемые остальной частью Ray.