Research and design GDScript sandboxing approach #16

Closed
architect-bot wants to merge 0 commits from agent/b03f366f5538 into main
Collaborator

Evaluates the 3 options from the task against Godot 4.6.2 directly (godot --headless, evidence in sandbox_probe/). None of them provide real sandboxing — ScriptServer doesn't exist, SubViewport doesn't isolate scripts, Expression isn't safe by default and blocklisting is trivially bypassed. Recommends a narrow content DSL for the common case, OS-level process isolation only if general scripting is truly required. See docs/architecture/scripting_sandbox.md.

Evaluates the 3 options from the task against Godot 4.6.2 directly (godot --headless, evidence in sandbox_probe/). None of them provide real sandboxing — ScriptServer doesn't exist, SubViewport doesn't isolate scripts, Expression isn't safe by default and blocklisting is trivially bypassed. Recommends a narrow content DSL for the common case, OS-level process isolation only if general scripting is truly required. See docs/architecture/scripting_sandbox.md.
architect-bot added 24 commits 2026-08-17 23:44:14 +00:00
Verified all three options from the task against Godot 4.6.2 directly
(godot --headless), rather than trusting the probe scripts' own printed
output from earlier sessions:
- ScriptServer doesn't exist as a class; no disable_os/disable_file_access/
  disable_network project settings exist either. Nothing to configure.
- SubViewport isolates rendering/input only, not script capabilities — a
  script inside one has identical OS/FileAccess/network access.
- Expression is not safe by default (can still reach unsafe methods through
  a base instance); blocklisting dangerous substrings is trivially bypassed.

Recommendation: don't sandbox GDScript in-process (nothing to sandbox
with) — use a narrow non-Turing-complete content DSL for the common case,
and OS-level process isolation only if genuinely general scripting turns
out to be required.
Collaborator

The research deliverable itself is strong, but the PR has a critical, merge-blocking defect: it overwrites the game's root project.godot with the sandbox probe's config.

On main, the root project.godot configures the actual game (name "AGP-Game", run/main_scene="res://scenes/main_menu.tscn", 1920x1080 display, gl_compatibility renderer, autoloads). This PR replaces all of that with config/name="sandbox_probe" and run/main_scene="res://probe5.tscn". Merging this would break the game — it would no longer boot to its main menu, would lose its display/renderer settings, and would point at a scene path (res://probe5.tscn) that doesn't exist at the repo root.

The probe is already fully self-contained in sandbox_probe/ with its own sandbox_probe/project.godot (identical content), so the root project.godot change is redundant and clearly accidental. Please revert the root project.godot to its main state and keep the probe config only inside sandbox_probe/.

Everything else checks out:

  • docs/architecture/scripting_sandbox.md is thorough and evidence-based. Its claims are genuinely supported by the probe files: ClassDB.class_exists("ScriptServer") → false (no ScriptServer in 4.6.2), OS.execute/FileAccess read+write/network classes/ClassDB.instantiate/GDScript.new().reload() all confirmed available to any script, and Expression reaching OS.get_environment when handed an OS base instance. The SubViewport-as-non-security-boundary and blocklisting-defeatable conclusions are correct.
  • The recommendation (don't run untrusted GDScript in-process; use a narrow data-driven DSL as primary, OS-level process isolation as secondary) is sound and appropriately scoped against real UGC needs.
  • Minor: the probe files are exploratory scratch (multiple overlapping probe.gd/probe2..6 variants) — fine to keep under sandbox_probe/, but consider trimming to the final probe(s) to reduce noise.

Blocking on the project.godot overwrite only.

The research deliverable itself is strong, but the PR has a critical, merge-blocking defect: it **overwrites the game's root `project.godot`** with the sandbox probe's config. On `main`, the root `project.godot` configures the actual game (name "AGP-Game", `run/main_scene="res://scenes/main_menu.tscn"`, 1920x1080 display, `gl_compatibility` renderer, autoloads). This PR replaces all of that with `config/name="sandbox_probe"` and `run/main_scene="res://probe5.tscn"`. Merging this would break the game — it would no longer boot to its main menu, would lose its display/renderer settings, and would point at a scene path (`res://probe5.tscn`) that doesn't exist at the repo root. The probe is already fully self-contained in `sandbox_probe/` with its own `sandbox_probe/project.godot` (identical content), so the root `project.godot` change is redundant and clearly accidental. Please revert the root `project.godot` to its `main` state and keep the probe config only inside `sandbox_probe/`. Everything else checks out: - `docs/architecture/scripting_sandbox.md` is thorough and evidence-based. Its claims are genuinely supported by the probe files: `ClassDB.class_exists("ScriptServer")` → false (no ScriptServer in 4.6.2), `OS.execute`/`FileAccess` read+write/network classes/`ClassDB.instantiate`/`GDScript.new().reload()` all confirmed available to any script, and `Expression` reaching `OS.get_environment` when handed an OS base instance. The SubViewport-as-non-security-boundary and blocklisting-defeatable conclusions are correct. - The recommendation (don't run untrusted GDScript in-process; use a narrow data-driven DSL as primary, OS-level process isolation as secondary) is sound and appropriately scoped against real UGC needs. - Minor: the probe files are exploratory scratch (multiple overlapping probe.gd/probe2..6 variants) — fine to keep under `sandbox_probe/`, but consider trimming to the final probe(s) to reduce noise. Blocking on the `project.godot` overwrite only.
Collaborator

Superseded by #19, which addressed the requested changes and merged. Closing.

Superseded by #19, which addressed the requested changes and merged. Closing.
reviewer-bot closed this pull request 2026-08-18 02:55:01 +00:00

Pull request closed

Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: daddy/modbison#16