Skip to content

Three memory-safety bugs in Godot's untrusted-file parsers

found three serious bugs in Godot 4.7 in an audit conducted with an LLM agent. The bugs are due to missing bounds checking in code that reads untrusted files. Using files that are deliberately crafted, Godot can be made to read or write beyond an allowed buffer. I reported the bugs to the Godot security team through email. I provided an example of effective reproduction and suggested a solution for each.

Two of the three bugs have been in Godot since the engine was first open-sourced in 2014. The third is nine years old, introduced in 2017. All three are present, unchanged, in current builds as of this writing (2026-09-21). My audit was not extensive and it turned up other leads which I did not explore.

Working PoCs are not included in this disclosure. They were provided privately to the Godot security team and may be shared on request with maintainers, CVE authorities, researchers, or other parties where I judge disclosure appropriate.

How they were found

I directed the audit by prompting a Claude Code agent, using Opus 4.8, to:

Find serious bugs in Godot 4.7 that were previously unknown.

The agent then downloaded the Godot source, identified promising areas, found the bugs and created working reproduction projects that demonstrated them, causing crashes against official release binaries. The first working reproduction was ready a couple of hours after the initial prompt. Others followed later that same day.

How these bugs activate

The .hdr bug fires during Godot's automatic import of assets. The .res bug fires when a malicious binary resource is loaded. The translation bug fires later, the first time code looks up a string in a maliciously crafted translation file. Some exported games may be at risk: any game that loads .hdr images, binary resources, or translations it did not ship (e.g. mods, downloads, user uploads).

Severity

The way bugs of this kind have been treated in the past suggests that they warrant serious attention.

Similar buffer bugs were found in 2021 with Godot's TGA decoder - CVE-2021-26825 and CVE-2021-26826. The issues were assigned CVE ids and scored 7.8 on CVSS - qualifying as 'high' severity.

By directing an LLM agent I found three serious memory-safety bugs in Godot 4.7. I created reproductions that caused Godot to crash but didn't create any weaponised payloads - that would require significantly more effort.

The bugs

A file format defines numbers intended to hold data describing the file. Those numbers don't have to be true. In the three bugs I found Godot trusts these numbers without checking them against the file's real characteristics.

HDR file loader: .hdr files are special images often used for sky or lightmaps. To keep the files small, they contain special instructions to encode things like 'repeat this color for the next 20 pixels'. If Godot imports a maliciously created .hdr file, and sees instructions to create more pixels of color than it has reserved space for, it will write past the end of the buffer it reserved for the image, into memory it's not supposed to touch with the operation. Godot doesn't check that there's room to carry out the operation. The data written out of bounds comes from the file the attacker crafted.

Binary resource loader: When loading .res files Godot looks for special values in them that are supposed to announce how long a corresponding string inside that file is, so Godot can allocate the right amount of memory to hold it. But an attacker can falsely author a negative integer as a string length. Godot sees the negative value, treats it as effectively zero, and concludes that it's not necessary to allocate space for the string. Then Godot interprets that same value as a huge unsigned int when copying from the file into memory, causing the data to be written unsafely into adjacent areas.

Translation loader: The translation loader can be made to read past the end of its buffers by a translation file deliberately designed to point an index far past the real buffer. This can crash Godot, or make a tr() call return raw bytes from elsewhere in the process's memory as if they were the translated string.

The fixes

Before trusting any file metadata, check that file lengths or indexes fit within the relevant buffer. Reject the file if there's any mismatch. I included a suggested patch with each report.

Response from the Godot team

On 2026-09-19 Clay John replied to the Godot issue with the following comment.

Thank you for your interest in contributing to Godot.

Our security team reviewed your emails and determined that there were no security issues. In all three cases, the vulnerability requires the attacker to already have control over your filesystem and feed in specially crafted files to the Godot editor in order to make it write to an out of memory location and crash.

Please go ahead and open a regular bug reports since we do routinely fix memory safety issues as we discover them. There is no need for any special handling.

Please remember to follow the bug report template and note our rules on AI-assisted contributions https://contributing.godotengine.org/en/latest/development/contribution_rules.html#ai-assisted-contributions

Also, as a point of advice. If you expect an answer to your emails, it is best to hand write them so that it is clear they are coming from a person. Using an LLM to assist you is fine, but it was very clear in the emails that the reports and email were generated by an LLM. Our volunteers have to prioritize how they spend their time so it is no surprise they decided not to respond after confirming that the reports were ordinary memory safety issues and not security issues.

These are security issues.

John is wrong when he claims that the vulnerabilities require an attacker to already have control over the filesystem. The team seems only to have considered how these bugs affect users running the Godot editor, and not their implications for exported games. An exported Godot game might deliberately accept and parse player/community uploaded files. In a game like this an attacker could use the bugs as memory-corruption/read primitives without having general system control.

In February 2024, Godot lead developer Juan Linietsky wrote about 'real security', that it's "where you care that what you are doing can't become an attack vector for common types of exploits (such as stack or memory overwriting, predictor attacks, etc)" and "on the Godot side, the only real security measures are when handling marshalls, protcols and binary files." The three bugs I reported are in code that loads binary files.

The US National Vulnerability Database scored two Godot TGA decoder overflow bugs that received CVEs in 2021. The database recorded that the attacker needed no privileges on the victim's machine and the vulnerability needs only for the victim to load the file. Both issues scored 7.8 out of 10 for severity. The three bugs I reported share the same relevant characteristic: they are unsafe memory operations triggerable by maliciously crafted files.

A point of order: My HDR bug report included a note: "This report was drafted by Claude Opus 4.8 and Claude Sonnet 4.6, directed by me." The other two stated: "Security report and reproduction case created by Claude Sonnet 4.6." When John says the emails were "clearly LLM-written" this misleadingly implies that this was surreptitious LLM use uncovered by the team, rather than something I announced clearly myself.

About the advice to hand-write my reports when I communicate with Godot maintainers, I'd like to offer this piece of advice in return: The relevant questions for maintainers should be whether an incoming report is correct, reproducible, and useful. 'Did an AI model write it?' is a terrible proxy for that, even though bad AI assisted contributions undoubtedly exist. I've read the justifications, and the problem of overwhelmed maintainers is a strong reason to engage with this technology more thoughtfully:

  • Use LLMs to triage reports and PRs, and optionally to coach contributors in improving their contributions. Only contributions that are already filtered, and improved where necessary, reach human maintainers, protecting their time, energy, and enthusiasm.
  • Use LLMs to audit the project yourselves so that these kinds of vulnerabilities don't need to be reported to you in the first place.

Timeline

I reported the HDR loader bug to security@godotengine.org on 2026-06-22, with a working reproduction and a fix. The next day I reported the binary resource loader and translation loader bugs to the same address, also with working reproductions and fixes. I stated that I would disclose the bugs publicly after 90 days.

On 2026-09-18 I sent a reminder to security@godotengine.org stating the planned publication date of this document, and an earlier draft of it. On the same day I posted an issue on the Godot engine's GitHub repository saying I'd sent these emails three months ago without reply and would be publishing the disclosure on the 21st.

On 2026-09-19 Clay John replied to the github issue stating that the security team had determined that the bugs were not security issues, and recommended that they be filed as regular bugs. John closed the issue as "not planned."

On 2026-09-20 I requested CVE identifiers for the three bugs from MITRE.

I published this disclosure on 2026-09-21. As of this date Godot 4.7.2-stable and 4.8 development branches still carry the three bugs.

Did you enjoy this article?

Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.

Across the AtmosphereDiscussions