# Open CASCADE Technology (OCCT) Multiple Memory Safety Vulnerabilities
**Vendor**: Open CASCADE SAS (dev.opencascade.org)
**Affected**: OCCT ≤ 7.8.1, master through commit c540f316
**Reporter**: Feng Ning, Innora Security Research (feng@innora.ai)
**Disclosure**: 2026-04-30
| CVE | Component | CWE | CVSS |
|-----|-----------|-----|------|
| CVE-2026-42476 | STL ASCII parser — RWStl_Reader::ReadAscii | CWE-125 | 5.5 |
| CVE-2026-42477 | OBJ parser — RWObj_Reader::read | CWE-125 | 5.5 |
| CVE-2026-42478 | VRML parser — VrmlData_IndexedFaceSet::TShape | CWE-125 | 5.5 |
| CVE-2026-42479 | VRML parser — VrmlData_IndexedLineSet::TShape | CWE-125 | 5.5 |
| CVE-2026-42480 | VRML parser — VrmlData_Scene::ReadLine | CWE-125 | 5.5 |
| CVE-2026-42481 | IGES/STEP parsers — BSplSLib, multiple | CWE-125 | 5.5 |
---
## CVE-2026-42476 — STL ASCII Parser Heap OOB Read
In `src/DataExchange/TKDESTL/RWStl/RWStl_Reader.cxx`, `RWStl_Reader::ReadAscii()` feeds triangle data directly into `sscanf` without first checking whether the buffer returned by `Standard_ReadLineBuffer::ReadLine()` is large enough to hold it. Craft an STL file so that `ReadLine` returns a 1–3 byte buffer and those `sscanf` calls will read past the end of the allocation.
Two distinct code paths hit the same root cause; they share this CVE.
**Fix**: validate `ReadLine` return length before parsing.
---
## CVE-2026-42477 — OBJ Parser Heap OOB Read
`RWObj_Reader::read()` lives in `src/DataExchange/TKDEOBJ/RWObj/RWObj_Reader.cxx`. It passes `aLine+2` to `pushIndices()` with no check that the arithmetic stays within the line buffer. A crafted OBJ file whose index line is minimal produces a 1-byte heap read past the end of the allocation.
**Fix**: check `aLine + 2` does not exceed line buffer length before dereferencing.
---
## CVE-2026-42478/42479/42480 — VRML V2.0 Parser OOB Read (Three Paths)
Three functions across `src/DataExchange/TKDEVRML/` all read array index values from VRML node fields and use them without bounds validation. Each path is independently reachable.
- **CVE-2026-42478**: `VrmlData_IndexedFaceSet::TShape()` uses `coordIndex` values as direct array subscripts with no `>= 0` or `< coordCount` guard. An off-by-one combined with integer-to-negative conversion opens the door to wild-address reads — ASAN scores this SCARINESS: 20.
- **CVE-2026-42479**: `VrmlData_IndexedLineSet::TShape()` is the same class of bug. Heap buffer overflow read, 24-byte stride.
- **CVE-2026-42480**: `VrmlData_Scene::ReadLine()` declares `aBuffer[256]` on the stack at line 328. Feed it a VRML node with a line longer than 8376 bytes and the stack blows at offset 8376 per ASAN.
**Fix**: add `>= 0 && < arraySize` bounds checks before all coordIndex/normalIndex dereferences; cap `ReadLine` input at buffer size.
---
## CVE-2026-42481 — IGES/STEP Parser Multiple OOB Reads (V8_0_0_rc5)
Fuzzing V8_0_0_rc5 turned up several OOB-read paths in the IGES and STEP parsers:
- `Geom2d_BSplineCurve::EvalD0()` — when knot multiplicity is crafted to push evaluation outside pole bounds, the function reads 8 bytes past the end of the allocated pole array.
- The STEP and IGES parsers share additional OOB-read paths in `DataExchange/`, also surfaced by the fuzzer.
**Fix**: add index range validation before pole/knot array access in B-spline evaluation.
---
## Proof of Concept
Minimal crash inputs, ASAN-confirmed at 20/20 reproducibility:
echo "solid s\nfacet normal 0 0 0\nouter loop\nvertex 0 0 0\nendloop\nendfacet\nendsolid" | tr '\n' '\n' > min.stl
Confirmed on OCCT 7.8.1 and master (commit c540f316).
---
*Innora Security Research — https://innora.ai*