Skip to content

Fixed addons being unable to read project settings #1180 - #1181

Merged
Arctis-Fireblight merged 1 commit into
Redot-Engine:devfrom
Arctis-Fireblight:fix-issue-1180
Jan 28, 2026
Merged

Fixed addons being unable to read project settings #1180#1181
Arctis-Fireblight merged 1 commit into
Redot-Engine:devfrom
Arctis-Fireblight:fix-issue-1180

Conversation

@Arctis-Fireblight

@Arctis-Fireblight Arctis-Fireblight commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

PR #1142 fixes a remote code execution vulnerability by disallowing deserialization of objects by default. The PR correctly bypasses the security measure when loading project settings from project.godot, but some addons also store their configuration settings in there as well, and are not aware of this security feature and thus the call will generate an error. This commit adds a check to determine if we are trying to access a project file, and if so, to allow for deserialization of raw objects which is needed for reading project settings.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed configuration parsing for .godot project files so object data is correctly recognized and loaded during file parsing, improving compatibility and preventing missing or misinterpreted project settings.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 28, 2026

Copy link
Copy Markdown

Walkthrough

A guard was added to ConfigFile::_parse to set p_allow_objects = true when the input path ends with project.godot (case-insensitive), forcing object allowance during parsing of Godot project config files.

Changes

Cohort / File(s) Summary
ConfigFile guard
core/io/config_file.cpp
Inserted a conditional at the start of _parse to force p_allow_objects = true when the input path ends with project.godot (case-insensitive), altering initial parsing control flow.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fixed addons being unable to read project settings #1180' directly addresses the main issue resolved by the PR: enabling addons to read project settings after object deserialization was disabled for security reasons.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
core/io/config_file.cpp (1)

276-282: Scope object allowance to the actual project settings file only.

This enables object deserialization for any “.godot” file, which widens the surface area beyond the intended project.godot and risks reintroducing the earlier RCE vector if arbitrary .godot configs are loaded. Prefer restricting to the canonical project settings path (or move this exception to the ProjectSettings load site where the file is known to be trusted).

🔧 Possible tightening (filename-only)
-	if (p_path.to_lower().ends_with(".godot")) {
+	if (p_path.get_file().to_lower() == "project.godot") {
 		p_allow_objects = true;
 	}

@Arctis-Fireblight

Copy link
Copy Markdown
Contributor Author

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)

core/io/config_file.cpp (1)> 276-282: Scope object allowance to the actual project settings file only.

This enables object deserialization for any “.godot” file, which widens the surface area beyond the intended project.godot and risks reintroducing the earlier RCE vector if arbitrary .godot configs are loaded. Prefer restricting to the canonical project settings path (or move this exception to the ProjectSettings load site where the file is known to be trusted).

🔧 Possible tightening (filename-only)

-	if (p_path.to_lower().ends_with(".godot")) {
+	if (p_path.get_file().to_lower() == "project.godot") {
 		p_allow_objects = true;
 	}

@coderabbitai
This was a deliberate design choice, since I believe the project file does not have to be named project.godot, I think this is just the default.
By rights, user code should not be loading .godot files from other sources let alone outside of the editor. The increase in attack surface for the RCE is minimal, especially when considering that users are commonly importing code and extensions from Godot, which does not have the anti-RCE measure at all, only Redot does. A balance must be struck to retain backwards compatibility with Godot projects and extensions as well as providing extra security.

@coderabbitai

coderabbitai Bot commented Jan 28, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for how project files are loaded and whether custom names are supported
rg -n -C3 "project\.godot|project_settings.*load|load.*project" --type=cpp | head -100

Length of output: 6700


🏁 Script executed:

#!/bin/bash
# Look for any documentation or code that shows project file name flexibility
rg -n "project.*file.*name|custom.*project.*file" --type=cpp --type=h | head -50

Length of output: 5450


🏁 Script executed:

#!/bin/bash
# Search for ProjectSettings class and how it identifies/loads the project file
ast-grep --pattern 'class ProjectSettings {
  $$$
}'

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Find where the project file path/name is determined
rg -n "\.godot.*path|project.*path.*godot" --type=cpp -C2 | head -80

Length of output: 7188


🏁 Script executed:

#!/bin/bash
# Search for ProjectSettings::setup and how it loads the project file
rg -n "ProjectSettings.*setup|setup.*project" --type=cpp -C5 | head -100

Length of output: 8411


🏁 Script executed:

#!/bin/bash
# Look at the ProjectSettings class definition and its load methods
fd -e h "project_settings.h" --exec cat {}

Length of output: 26076


🏁 Script executed:

#!/bin/bash
# Check if there's any command-line argument or config that allows custom project file names
rg -n "project.*file.*arg|--project|custom.*project.*name" --type=cpp -C3

Length of output: 3787


🏁 Script executed:

#!/bin/bash
# Look at the ProjectSettings::setup implementation to see if it supports custom filenames
rg -n "Error.*ProjectSettings::setup|ProjectSettings::setup" --type=cpp -A20 | head -150

Length of output: 1982


🏁 Script executed:

#!/bin/bash
# Check the constructor implementation to see if custom project file names are supported
rg -n "ProjectSettings::ProjectSettings.*String" --type=cpp -A15

Length of output: 710


🏁 Script executed:

#!/bin/bash
# Look for any code that determines the project file name
rg -n "project_file|project.*filename|\.godot.*file" --type=cpp -C2 | grep -i "name\|filename" | head -40

Length of output: 3193


🏁 Script executed:

#!/bin/bash
# Look at the _setup implementation to see if project.godot is hardcoded
rg -n "Error ProjectSettings::_setup" --type=cpp -A50 | head -100

Length of output: 4321


🏁 Script executed:

#!/bin/bash
# Search for where "project.godot" string literal is used in setup/load functions
rg -n '"project\.godot"' --type=cpp -C3 | head -80

Length of output: 7302


🏁 Script executed:

#!/bin/bash
# Check if there's any flexibility in the project file name in the setup process
ast-grep --pattern 'if ($_.ends_with("project.godot")) {
  $$$
}'

Length of output: 15554


@Arctis-Fireblight, thank you for the detailed explanation of your design rationale. I understand the balance you're striking between security and backwards compatibility with Godot projects and extensions.

However, based on my examination of the codebase, I found that the project file name is actually hardcoded to "project.godot" throughout the engine. For example:

  • In core/config/project_settings.cpp:648, the setup loads "res://project.godot" explicitly
  • In main/main.cpp:1714, command-line argument processing checks arg.ends_with("project.godot")
  • The project manager and editor consistently reference "project.godot" by name

While command-line paths can reference the file by its full path, the actual filename must be "project.godot" (not a custom name). This means you could potentially restrict the check to p_path.get_file().to_lower() == "project.godot" without losing functionality.

That said, I respect your decision on the security/compatibility tradeoff. Your point about Godot projects and extensions not having this anti-RCE measure is valid context. If you're comfortable with the slightly broader scope, the current implementation achieves your compatibility goals.


✏️ Learnings added
Learnt from: Arctis-Fireblight
URL: https://github.com/Redot-Engine/redot-engine/pull/1181

Timestamp: 2026-01-28T05:07:14.139Z
Learning: In Redot Engine, the fix for issue `#1180` deliberately allows object deserialization for any ".godot" file (not just "project.godot") to maintain backwards compatibility with Godot projects and extensions, which don't have the anti-RCE measure. This is a conscious security/compatibility tradeoff approved by the project maintainer.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

PR Redot-Engine#1142 fixes a remote code execution vulnerability by disallowing deserialization of objects by default.
The PR correctly bypasses the security measure when loading project settings from `project.godot`, but some addons also store their configuration settings in there as well, and are not aware of this security feature and thus the call will generate an error.
This commit adds a check to determine if we are trying to access a project file, and if so, to allow for deserialization of raw objects which is needed for reading project settings.
@Arctis-Fireblight
Arctis-Fireblight merged commit bbf086d into Redot-Engine:dev Jan 28, 2026
17 checks passed
@github-project-automation github-project-automation Bot moved this from Open to Done in Engine Overview Jan 28, 2026
@Arctis-Fireblight
Arctis-Fireblight deleted the fix-issue-1180 branch January 30, 2026 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

1 participant