
OpenMed < 1.5.2 RCE non autenticata tramite caricamento del modello del filtro privacy PII e trust_remote_code=True
Gravità: Critica, CVSS 4.0 9.3, CVSS 3.1 9.8 (assegnata da VulnCheck, il CNA)
Vettore (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
Vettore (v3.1): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Affetto: OpenMed < 1.5.2
Corretto in: 1.5.2
CWE: CWE-94 (Controllo Inadeguato della Generazione di Codice, Iniezione di Codice)
Scoperta e segnalata da: Sai Teja Erukude
Pubblicata: 2 giugno 2026
OpenMed precedente alla versione 1.5.2 contiene una vulnerabilità di esecuzione remota di codice non autenticata nel percorso di caricamento del modello privacy-filter per i dati PII.
Gli endpoint REST API POST /pii/extract e POST /pii/deidentify accettano un valore model_name dal corpo della richiesta. Nelle versioni vulnerabili, il dispatcher del privacy-filter utilizzava una corrispondenza ampia per sottostringa su questo valore controllato dall'attaccante. Un nome di modello come attacker/foo-privacy-filter-bar poteva quindi essere instradato verso il backend del privacy-filter.
Sulle distribuzioni non-MLX/Torch, quel backend caricava gli artefatti del modello Hugging Face tramite Transformers con trust_remote_code=True. Se il repository del modello controllato dall'attaccante conteneva codice Transformers personalizzato referenziato tramite auto_map in config.json o tokenizer_config.json, Transformers importava ed eseguiva quel codice Python durante il caricamento del modello o del tokenizer.
Il codice importato veniva eseguito con i privilegi del processo del servizio OpenMed.
Un attaccante remoto non autenticato che riesce a raggiungere la REST API di OpenMed può eseguire codice Python arbitrario sul server fornendo un identificatore di modello in stile Hugging Face malevolo in model_name.
A seconda della distribuzione del servizio, ciò può consentire di:
Il problema è raggiungibile attraverso entrambi gli endpoint PII poiché entrambi accettano model_name e utilizzano lo stesso percorso di estrazione PII/caricamento del modello:
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
}
Il flusso di controllo vulnerabile presenta due fallimenti del confine di fiducia:
model_name fornito dall'utente durante la selezione del backend del filtro per la privacy.trust_remote_code=True.Il dispatcher trattava qualsiasi identificatore di modello contenente privacy-filter come appartenente alla famiglia dei filtri per la privacy. Ciò consentiva a identificatori controllati dall'attaccante, ad esempio attacker/foo-privacy-filter-bar, di raggiungere un percorso di codice destinato ai modelli Privacy Filter attendibili di prima parte.
Una volta instradati lì, Transformers poteva caricare codice personalizzato controllato dall'attaccante tramite auto_map. Questa importazione avviene durante il caricamento del modello/tokenizer, prima che qualsiasi inferenza utile debba avere successo. Un payload di prova può quindi essere ridotto a:
from pathlib import Path
Path("marker.txt").write_text(
"custom Transformers code executed via trust_remote_code\n",
encoding="utf-8",
)
poc_exploit.py crea una directory locale innocua di un modello in stile Hugging Face il cui nome contiene privacy-filter. I moduli Transformers personalizzati generati scrivono un file marcatore quando vengono importati. Lo script invia poi una richiesta a un'istanza di test dell'API OpenMed con quella directory come model_name.
Il comportamento atteso sulle versioni vulnerabili di OpenMed è:
model_name controllato dall'attaccante.trust_remote_code=True.Eseguire solo contro un'istanza di test locale:
pip install -r requirements.txt
python poc_exploit.py --target http://127.0.0.1:8000 --endpoint /pii/extract
Se il servizio OpenMed viene eseguito in un ambiente che non può accedere alla directory locale generata, pubblica un modello di test equivalente su un repository Hugging Face controllato e passa esplicitamente quell'identificatore:
python poc_exploit.py \
--target http://127.0.0.1:8000 \
--model-name your-org/foo-privacy-filter-bar \
--marker marker.txt
Eseguire l'aggiornamento a OpenMed 1.5.2 o versione successiva.
OpenMed 1.5.2 separa il routing dalla fiducia:
privacy-filter non vengono più instradati attraverso il percorso attendibile del privacy-filter.PrivacyFilterTorchPipeline imposta trust_remote_code su False per impostazione predefinita.OPENMED_TRUSTED_REMOTE_CODE_MODELS.Se l'aggiornamento immediato non è possibile:
model_name controllati dall'utente a Transformers con trust_remote_code=True.| Data | Evento |
|---|---|
| 18 maggio 2026 | Vulnerabilità inviata a VulnCheck |
| 20 maggio 2026 | VulnCheck ha avviato l'attività di divulgazione coordinata |
| 22 maggio 2026 | CVE-2026-47117 assegnata in via provvisoria |
| 1 giugno 2026 | Correzione di OpenMed 1.5.2 revisionata e confermata |
| 2 giugno 2026 | CVE-2026-47117 pubblicata |
Scoperta e segnalata da Sai Teja Erukude.
La divulgazione è stata coordinata tramite VulnCheck.