Jul 29, 2026·5 min read·17 visits
A heap-based buffer overflow vulnerability in Assimp's Half-Life 1 MDL parser (<= 5.4.3) allows local attackers to cause denial of service or potentially execute arbitrary code via a malformed model file.
CVE-2025-6120 is a critical memory corruption vulnerability in the Open Asset Import Library (Assimp) affecting versions up to and including 5.4.3. The flaw is located in the Half-Life 1 MDL file format loader, specifically within the read_meshes function in HL1MDLLoader.cpp. It arises due to a lack of verification checks on array, bone, skin, or vertex indices parsed directly from a binary stream, resulting in a heap-based buffer overflow or out-of-bounds memory access.
The Open Asset Import Library (Assimp) is an open-source library designed to import and manipulate various 3D model formats. It is utilized in rendering engines, game development tools, asset pipelines, and visualization software. To parse these legacy formats, Assimp employs specific loader components designed for individual file extensions. One such module is the Half-Life 1 MDL loader, which parses historical game assets.
Legacy 3D format loaders present a significant attack surface because they often parse highly nested, binary, and complex structures. Because Assimp is implemented in C++, memory management is handled manually, requiring robust boundary checks on all parsed offsets and index parameters. A failure to validate these values can lead to severe memory corruption when processing corrupted or maliciously modified input files.
CVE-2025-6120 identifies a critical heap-based buffer overflow inside the HL1 MDL loader component. The vulnerability resides specifically within the read_meshes function located in the source file HL1MDLLoader.cpp. This weakness permits local attackers to supply malformed 3D assets that corrupt heap memory, causing the application to terminate unexpectedly or potentially execute arbitrary code.
The primary flaw within HL1MDLLoader::read_meshes lies in the handling of array index variables parsed directly from the MDL binary stream. When the loader encounters model structures, it initializes several heap-allocated arrays, including temp_bones_ and bind_pose_vertices. These arrays hold vertex, bone, and transformation matrices crucial for skeletal animation and mesh reconstruction.
During parsing, the loader retrieves index values such as bone indices pvertbone[k] and skin references pskinref[pmesh->skinref] from the MDL file stream. These indices are subsequently utilized as offsets to access elements inside the heap-allocated structures without any boundary validation. Because the parser trusts the file header and structure counts, it assumes all indices lie within the safe limits of the pre-allocated buffers.
When a malformed MDL file defines index values larger than the actual array bounds, the application accesses memory outside the allocated block. This causes heap-out-of-bounds reads when reading bone transforms, and heap-out-of-bounds writes when writing calculated vertices back to memory buffers. This unchecked array indexing constitutes a classic CWE-122 (Heap-based Buffer Overflow) vulnerability, leading to memory corruption.
The vulnerability exists in assimp/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp inside the read_meshes function. An analysis of the vulnerable commit b3a47a68fa0a379b1fa0788e4a5f448111cd2012 highlights multiple critical lines where indices are dereferenced without validation.
For example, the loader retrieves a bone index via pvertbone[k] and uses it to reference temp_bones_:
// Vulnerable code in HL1MDLLoader.cpp
bind_pose_vertices[k] = temp_bones_[pvertbone[k]].absolute_transform * aiVector3D(vert[0], vert[1], vert[2]);If the value of pvertbone[k] exceeds the bounds of the temp_bones_ vector, this operation triggers an out-of-bounds read, fetching a corrupted matrix that corrupts subsequent calculations. Similarly, normal bone arrays are processed without verification:
// Vulnerable code in HL1MDLLoader.cpp
const aiMatrix4x4 normal_matrix = aiMatrix4x4(temp_bones_[pnormbone[k]].absolute_transform).Inverse().Transpose();In addition, skin references are read through nested indexing operations:
// Vulnerable skin reference resolution
float texcoords_s_scale = 1.0f / (float)ptexture[pskinref[pmesh->skinref]].width;If pmesh->skinref or the resolved value inside pskinref is larger than the ptexture allocation limits, the system attempts to dereference an invalid memory address, causing an immediate crash or leaking adjacent heap memory structures.
To trace the logical progression of the exploit, it is necessary to examine how Assimp structures its model loader sequence. The following diagram illustrates the flow of untrusted input data from the file stream into the heap buffers of the HL1MDLLoader class:
The parser begins by reading file headers to determine buffer sizes. It then allocates memory based on these dimensions. The failure occurs because individual element indices within the body of the MDL structure are not validated against the allocation sizes defined in the file headers.
To execute an attack, a local adversary must construct a malformed Half-Life MDL file containing inconsistent internal headers. The exploit file defines a small number of bone elements to minimize heap allocation size while setting the bone indices of specific vertices to extremely large integer values. This misalignment ensures that when the file is processed, the memory access offset points outside the allocated boundaries.
An application utilizing Assimp must then ingest this file. Typical targets include asset conversion servers, local 3D model viewers, game development environments, or engine pipelines. When the application loads the file, the parser executes automatically, requiring no direct administrative privileges or authentication from the attacking entity.
Depending on the configuration of the heap and the precision of the index alignment, the out-of-bounds access can overwrite adjacent heap chunks. This can corrupt function pointers, virtual table pointers, or metadata belonging to neighboring objects. Successfully aligning and manipulating these structures can redirect execution flow to attacker-controlled memory, enabling arbitrary code execution under the permissions of the host process.
The primary remediation strategy is upgrading the Assimp library. Since this vulnerability is tracked as part of a collective fuzzer issue, standard patches should be tracked directly via the project repository. If your application does not require importing Half-Life 1 MDL models, you should disable the vulnerable loader entirely during compilation.
To disable the legacy MDL importer, compile Assimp from source using the following CMake build configuration flag:
cmake -DASSIMP_BUILD_MDL_IMPORTER=OFF ..This completely removes HL1MDLLoader and its associated attack surface from the compiled binary. For environments where the loader must remain active, implement robust sandboxing. Run the parsing process inside isolated sandboxes using gVisor, Docker, or systemd-seccomp profiles with restricted system call privileges to limit the impact of any potential sandbox escapes.
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
Assimp Open Asset Import Library | <= 5.4.3 | Not explicitly patched (Tracking issue active) |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-122 (Heap-based Buffer Overflow) |
| Attack Vector | Local / Client File Ingestion |
| CVSS v3.1 Score | 5.3 (Medium) |
| EPSS Score | 0.0021 |
| Exploit Status | Proof-of-Concept Available |
| CISA KEV Status | Not Listed |
A heap-based buffer overflow condition occurs when a buffer that is allocated on the heap portion of memory is written to with more data than the buffer can hold.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.