Security Advisory — ByteScan Security Research Lab

CVE-2026-39020
Denial of Service in Wings3D 2.4.1 via Crafted Wavefront OBJ File

Medium — 5.5
CVE ID
CVE-2026-39020
CVSS v3.1
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H — 5.5 (Medium)
CWE
CWE-754 — Improper Check for Unusual or Exceptional Conditions
Affected
Wings3D v2.4.1 (and prior versions)
Patch
Unpatched as of 2026-09-05
Discovered by
Mohammadreza Ashouri — ByteScan Security Research Lab
Published
2026-09-05

Description

Wings3D v2.4.1 is vulnerable to a denial of service via a crafted Wavefront OBJ file. The application's custom float parser, str2float_2/2, located in e3d_obj.erl at line 391, does not handle IEEE 754 special float values such as NaN, Inf, and -Inf.

When a user opens a crafted OBJ file containing these values, the Erlang runtime raises an unhandled function_clause exception that propagates through the import stack and crashes the application. No privileges are required beyond convincing the user to open a file.

Root Cause

Wings3D implements its own float parser rather than delegating to Erlang's standard list_to_float/1. The function str2float_2/2 in e3d_obj.erl uses Erlang pattern matching to parse digit sequences, but contains no clause to match the string "." in isolation or IEEE 754 special-value strings. When a vertex line such as v nan nan nan is encountered, the parser reaches a state where it is handed the atom "." with no matching clause, triggering a function_clause exception.

Crash call chain (from Erlang crash dump):

function_clause e3d_obj:'-str2float_2/2-fun-0-' "." [e3d_obj.erl, line 391] e3d_obj:str2float_2/2 [e3d_obj.erl, line 391] e3d_obj:parse/2 [e3d_obj.erl, line 212] e3d_obj:read_1/4 [e3d_obj.erl, line 195] e3d_obj:import_1/2 [e3d_obj.erl, line 59] e3d_obj:import/1 [e3d_obj.erl, line 46]

Proof of Concept

The following minimal OBJ file reliably triggers the crash. Save it as poc.obj and open it in Wings3D 2.4.1:

# CVE-2026-39020 PoC — Wings3D 2.4.1 DoS
# Mohammadreza Ashouri / ByteScan Security Research Lab

v nan nan nan
v 1.0 0.0 0.0
v 0.0 1.0 0.0
f 1 2 3

The crash is deterministic and immediate on import. Variants using inf, -inf, and exponent overflow (1e999) in vertex coordinates trigger the same code path.

Verify crash artifacts on macOS:

log stream --predicate 'process == "Wings3D"' --level debug &
ls -t /Library/Logs/DiagnosticReports/ | head -5

Impact

An attacker can craft a malicious .obj file that crashes Wings3D upon import. Exploitation requires user interaction: the victim must open the file. There is no evidence of code execution, memory disclosure, or privilege escalation. The impact is confined to application availability (crash / loss of unsaved work).

Discovery Method

This vulnerability was discovered using VULCAN, an LLM-guided semantic mutation fuzzer developed at ByteScan Security Research Lab. VULCAN generated IEEE 754 edge-case mutations of standard OBJ geometry files and fed them to Wings3D's import pipeline, identifying the parser crash path automatically.

Further information on the VULCAN project is available at bytescan.net/vulcan.html.

Disclosure Timeline

References

Wings3D source repository: github.com/dgud/wings
NVD entry: nvd.nist.gov/vuln/detail/CVE-2026-39020
CVE record: cve.org/CVERecord?id=CVE-2026-39020

Credits

Discovered and reported by Dr. Mohammadreza Ashouri, ByteScan Security Research Lab — audit@bytescan.netbytescan.netlinkedin.com/in/drashouri