diff --git a/sandbox_probe/probe3.gd b/sandbox_probe/probe3.gd new file mode 100644 index 0000000..1cb914a --- /dev/null +++ b/sandbox_probe/probe3.gd @@ -0,0 +1,111 @@ +extends Node + +func _ready(): + print("=== SANDBOX PROBE 3: Deep Sandboxing Mechanisms ===") + probe_script_restriction_apis() + probe_global_scope() + probe_classdb_restrictions() + probe_engine_singletons() + probe_network_restrictions() + probe_threading() + probe_expression_eval() + probe_resource_loading() + print("=== SANDBOX PROBE 3 END ===") + get_tree().quit() + +func probe_script_restriction_apis(): + print("--- Script restriction APIs ---") + # Does GDScript expose any way to restrict globals? + var gd = GDScript.new() + print(" GDScript methods: ", gd.get_method_list().map(func(m): return m.name)) + # Check for any 'restrict' or 'allow' methods on the language + var lang = GDScriptLanguage.new() + print(" GDScriptLanguage methods: ", lang.get_method_list().map(func(m): return m.name)) + # Check ScriptServer via Engine + print(" Engine.get_singleton_list contains ScriptServer: ", "ScriptServer" in Engine.get_singleton_list()) + +func probe_global_scope(): + print("--- Global scope ---") + # What globals are available to a script? + # Test if we can enumerate global classes + var globals = [] + for g in GlobalScope.get_singleton_list(): + globals.append(g) + print(" GlobalScope singletons: ", globals) + # Can we access ClassDB to enumerate classes? + print(" ClassDB.class_exists('OS'): ", ClassDB.class_exists("OS")) + print(" ClassDB.class_exists('FileAccess'): ", ClassDB.class_exists("FileAccess")) + print(" ClassDB.class_exists('TCPServer'): ", ClassDB.class_exists("TCPServer")) + +func probe_classdb_restrictions(): + print("--- ClassDB restrictions ---") + # Can we instantiate arbitrary classes? + var os = ClassDB.instantiate("OS") + print(" ClassDB.instantiate('OS') = ", os) + # Can we call static methods via ClassDB? + print(" ClassDB has method 'class_get_method_list': ", ClassDB.has_method("class_get_method_list")) + # Can we access the full class list? + var class_list = ClassDB.get_class_list() + print(" ClassDB.get_class_list() count: ", class_list.size()) + print(" First 10 classes: ", class_list.slice(0, 10)) + +func probe_engine_singletons(): + print("--- Engine singletons ---") + # What singletons are available? + var singletons = Engine.get_singleton_list() + print(" Engine singletons: ", singletons) + # Can we get a singleton by name? + for s in ["OS", "Engine", "ProjectSettings", "ResourceLoader", "ClassDB", "Input", "DisplayServer"]: + print(" Engine.has_singleton('", s, "'): ", Engine.has_singleton(s)) + +func probe_network_restrictions(): + print("--- Network restrictions ---") + # Can we make outbound HTTP requests? + var http = HTTPRequest.new() + print(" HTTPRequest.new() = ", http) + # Can we create a WebSocket client? + var ws = WebSocketPeer.new() + print(" WebSocketPeer.new() = ", ws) + # Can we access the network via PacketPeer? + var pp = PacketPeerUDP.new() + print(" PacketPeerUDP.new() = ", pp) + +func probe_threading(): + print("--- Threading ---") + # Can we spawn threads? + var thread = Thread.new() + print(" Thread.new() = ", thread) + # Can we use mutexes / semaphores? + var mutex = Mutex.new() + print(" Mutex.new() = ", mutex) + var sem = Semaphore.new() + print(" Semaphore.new() = ", sem) + +func probe_expression_eval(): + print("--- Expression evaluation ---") + # Godot's Expression class - can it evaluate arbitrary code? + var expr = Expression.new() + var err = expr.parse("1 + 2") + print(" Expression.parse('1+2') err=", err) + if err == OK: + var result = expr.execute() + print(" Expression.execute() = ", result) + # Can Expression access OS? + var expr2 = Expression.new() + err = expr2.parse("OS.get_environment('HOME')") + print(" Expression.parse('OS.get_environment') err=", err) + if err == OK: + var result2 = expr2.execute() + print(" Expression.execute() = ", result2) + +func probe_resource_loading(): + print("--- Resource loading ---") + # Can we load arbitrary resources? + var res = load("res://test_script.gd") + print(" load('res://test_script.gd') = ", res) + # Can we load from absolute paths? + var res2 = load("/etc/hostname") + print(" load('/etc/hostname') = ", res2) + # Can we use ResourceLoader directly? + var rl = ResourceLoader + print(" ResourceLoader.load('res://test_script.gd') = ", rl.load("res://test_script.gd"))