You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
harden(handlers): route every path-taking handler through McpPathValidator
The strong traversal validator from #347 was wired into only filesystem and
script handlers; ~12 other path-taking handlers used a bare begins_with("res://")
check (which does not reject "..") or no check at all (relying solely on
ResourceLoader.exists/load). This unifies all of them on McpPathValidator and
extends the validator with two checks.
Validator (utils/path_validator.gd):
- Reject embedded null bytes (truncation trap — the path written could differ
from the one validated).
- New for_write flag: write callers additionally refuse res://project.godot,
the res://.godot/ metadata dir, and .import sidecars (overwriting these
corrupts the project / import cache). Reads still permit inspecting them.
Signature is backward-compatible (for_write defaults to false).
Writers now validate with for_write=true (closes the traversal-write primitive):
resource_io.save_to_disk (backs resource/environment/texture/curve saves),
scene create_scene/save_scene_as, material/theme save helpers, filesystem
write_text, script create/patch.
Load/read sites now validate (closes the unvalidated-load surface, incl. the
@tool-script-execution risk from open_scene/create_node):
resource load/assign + nested object-property loads, scene open_scene,
script attach_script, node create_node scene_path + set_property resource
values, audio set_stream + list root, material assign/shader/list,
ui theme + stylebox, autoload path, curve set_points, particle mesh/
material/texture, material_values.load_texture.
Path-validation rejections report VALUE_OUT_OF_RANGE (the code these handlers
already used for "must start with res://"), keeping the INVALID_PARAMS catch-all
count under the audit-v2 #21 ceiling enforced by test_error_code_distribution.
The four pre-existing validator sites that already wrapped errors as
INVALID_PARAMS (filesystem, script create/read/patch/find, resource_io save,
material _validate_material_path) are left unchanged.
set_stream and the other load handlers now reject user:// (consistent with the
validator's existing test_user_prefix_rejected policy); the audio test fixture
moves from user:// to a res:// .tres registered via EditorFileSystem.update_file.
Tests (run against live Godot 4.6.3): validator unit tests for null-byte +
write blocklist + read-allows; scene traversal/manifest-overwrite rejection.
All affected suites pass (path_validator/scene/resource/node/material/theme/
curve/particle/ui/audio/autoload/filesystem/script). test_error_code_distribution
passes. Parse check clean.
Addresses advisory GHSA-p5x8-v25q-qw69 (GH-1, GH-2, GH-3, GH-4).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0 commit comments