| --- |
| tags: |
| - security |
| - proof-of-concept |
| - surrealml |
| --- |
| |
| # SurrealML process-abort PoC (`load_model` / embedded NUL byte) |
| |
| This repository contains a proof-of-concept `.surml` file for a responsibly-disclosed |
| vulnerability in [`surrealdb/surrealml`](https://github.com/surrealdb/surrealml) (tested at commit |
| `152ac2d508f1bae9ee62c46b7d211d80e40a6425`), reported via huntr's Model File Vulnerability |
| program. |
| |
| ## What this file is |
| |
| `malicious_nul_name.surml` is a syntactically valid (but minimal) SurrealML container: a 4-byte |
| big-endian header-length prefix, a header whose `name` field is the literal string |
| `evil\x00name` (a raw embedded NUL byte, all other header fields left empty/fresh), and 16 bytes |
| of placeholder model data. It follows exactly the header format documented and unit-tested in the |
| project's own `modules/core/src/storage/header/mod.rs`. |
| |
| ## What happens when you load it |
| |
| ```python |
| import ctypes |
| lib = ctypes.CDLL("libc_wrapper.so") # or .dll / .dylib |
| lib.load_model(b"malicious_nul_name.surml") |
| ``` |
| |
| `load_model()` reads and parses the file successfully (the header format tolerates an embedded |
| NUL byte fine), then panics while converting the `name` field to a C string |
| (`CString::new(name).unwrap()` at `modules/c-wrapper/src/api/storage/load_model.rs:124`), since a |
| `CString` cannot represent an interior NUL byte. Because `load_model` is a plain `extern "C" fn` |
| rather than `extern "C-unwind"`, this panic aborts the entire host process — it cannot be caught |
| as an exception by a Python/Node/etc. caller, and no error result is ever returned. |
|
|
| A single ~65-byte file is enough to kill any process that calls `load_model()` on it — no |
| inference, no other API call required. |
|
|
| See the reporter's full write-up submitted via huntr for the complete technical analysis, the |
| related prior-art discussion (GitHub issue |
| [surrealdb/surrealml#20](https://github.com/surrealdb/surrealml/issues/20), a similar |
| "malformed file crashes the whole server" report from 2024 that was reopened after an incomplete |
| fix), and a second, unrelated finding (a use-after-free in the Python client's `to_bytes()`). |
|
|
| ## Scope note |
|
|
| This PoC is provided solely for the purpose of responsible vulnerability disclosure and |
| reproduction by the `surrealml` maintainers / huntr triage team. It is not intended for any other |
| use. |
|
|