oss-sec mailing list archives
Godot 4.x: heap out-of-bounds read in OptimizedTranslation message lookup
From: Tomasz Kaye <tomasz.brain () gmail com>
Date: Wed, 14 Oct 2026 12:11:48 +0200
Three memory-safety bugs in Godot 4's untrusted-file parsers were publicly disclosed on 2026-09-21 [1]. This thread covers the OptimizedTranslation bug. Affected versions: Godot 4.7-stable, official release build, verified. Earlier versions presumed affected. The loader has been in the engine since 2014 (commit 0b806ee0fc). Unpatched as of 2026-10-13 (master, 4.7.2, 4.7.1, 4.7). Description: OptimizedTranslation::get_message (core/string/optimized_translation.cpp) looks up strings through a hash table read verbatim from the compiled translation resource. A crafted .translation or .tres resource of this type is a full control surface: the uint32_t table entry is used as an index into the bucket table with no bounds check — only the sentinel 0xFFFFFFFF is rejected — and the bucket's string offset is used against the strings array without a bounds check. As of 4.7-stable the unchecked bucket load is at line 259 and the unchecked string read at line 277; the identical pattern is present in get_translated_message_list() (line 299). Impact: Crash: the first tr() call through a far out-of-range entry faults, deterministically on stock 64-bit binaries, editor and export templates. Information disclosure: tr() returns bytes read from an attacker-chosen offset past the end of the strings buffer reaching GDScript callers, game UI, logs, or network output. The translation loader ships in export templates; an exported game that loads player- or community-supplied translation resources runs this code on untrusted input. Reproduction: Archive godot47_optimized_translation_oob_repro.zip (README, bug_analysis.md, make_repro.py; crash and info-leak variants of the crafted resource), with extracted contents and per-bug README: https://github.com/bitbutter/godot-security-pocs/tree/main/2026-09-untrusted-file-parsers/optimized-translation SHA-256: 19cc54698b40c15e214ce310307fc854b58e631e577c61647aca12ab442d0a70 Crash variant: the first tr() call faults on a stock 64-bit binary. Leak variant: tr() returns heap bytes as the translated string; confirmed during the audit on an official 4.7 build without instrumentation. Under AddressSanitizer the leak variant reports heap-buffer-overflow READ at optimized_translation.cpp:277. The same archive was distributed with the original report and is linked from the correspondence section of the disclosure post [1]. Fix status: Unpatched as of 2026-10-13 (master, 4.7.2, 4.7.1, 4.7). CVE status: Requested from MITRE's CVE Numbering Authority of Last Resort (CNA-LR) on 2026-09-20, prior to publication. No IDs assigned as of 2026-10-14; this thread will be self-replied when IDs arrive. Timeline 2026-06-23 — reported privately to security () godotengine org with reproduction and suggested patch. 2026-09-18 — public notice: https://github.com/godotengine/godot/issues/123608 2026-09-19 — vendor response classifying the issues as not security issues: https://github.com/godotengine/godot/issues/123608 Credit: Found during an automated audit directed by the reporter (LLM-driven source analysis; Claude Code — discovery by Opus 4.8, report and reproduction by Sonnet 4.6). Reproductions verified against official release binaries. Reported and disclosed by Tomasz Kaye. [1] https://axeghost.offprint.app/a/3mvs6zo4blo23-three-memory-safety-bugs-in-godots-untrusted-file-parsers
Current thread:
- Godot 4.x: heap out-of-bounds read in OptimizedTranslation message lookup Tomasz Kaye (Oct 14)
