fix(scripting): resolve Medium code-review finding (Core.Scripting-010)

Add ScriptSandboxTests cases for all forbidden-namespace deny-list
vectors that lacked test coverage: System.Threading.Thread,
System.Threading.Tasks.Task.Run (newly denied per Core.Scripting-003),
System.Runtime.InteropServices.Marshal, and Microsoft.Win32.Registry.
The 001/002 type-granular and node-form vectors were already covered by
the -001/-002 resolution commits. All 79 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-22 09:23:29 -04:00
parent a6de04a297
commit a17de80cdb

View File

@@ -385,4 +385,65 @@ public sealed class ScriptSandboxTests
ex.Diagnostics[0].Location.ShouldNotBeNull();
}
}
// --- Core.Scripting-010: remaining forbidden-namespace vectors not previously tested ---
// System.Threading.Thread, System.Threading.Tasks, System.Runtime.InteropServices, and
// Microsoft.Win32 were all in ForbiddenNamespacePrefixes but had no test asserting their
// rejection. Adding them here closes the coverage gap that allowed Core.Scripting-001 and
// -002 to go undetected.
[Fact]
public void Rejects_Thread_new_at_compile()
{
// System.Threading.Thread is in ForbiddenNamespacePrefixes — raw thread creation
// in a script would bypass the per-evaluation timeout and tie up a thread-pool thread
// indefinitely. (Core.Scripting-010.)
Should.Throw<ScriptSandboxViolationException>(() =>
ScriptEvaluator<FakeScriptContext, int>.Compile(
"""
var t = new System.Threading.Thread(() => { });
t.Start();
return 0;
"""));
}
[Fact]
public void Rejects_Tasks_TaskRun_at_compile()
{
// System.Threading.Tasks is now in ForbiddenNamespacePrefixes (Core.Scripting-003).
// Scripts are synchronous predicates — background tasks would outlive the evaluation
// timeout. (Core.Scripting-010.)
Should.Throw<ScriptSandboxViolationException>(() =>
ScriptEvaluator<FakeScriptContext, int>.Compile(
"""
var t = System.Threading.Tasks.Task.Run(() => 42);
return 0;
"""));
}
[Fact]
public void Rejects_InteropServices_at_compile()
{
// System.Runtime.InteropServices gives access to native memory and COM — clearly
// outside the safe predicate surface. (Core.Scripting-010.)
Should.Throw<ScriptSandboxViolationException>(() =>
ScriptEvaluator<FakeScriptContext, int>.Compile(
"""
var p = System.Runtime.InteropServices.Marshal.AllocHGlobal(256);
return 0;
"""));
}
[Fact]
public void Rejects_Win32_Registry_at_compile()
{
// Microsoft.Win32 provides registry access — not appropriate from a sandboxed
// SCADA predicate. (Core.Scripting-010.)
Should.Throw<ScriptSandboxViolationException>(() =>
ScriptEvaluator<FakeScriptContext, int>.Compile(
"""
var k = Microsoft.Win32.Registry.CurrentUser;
return 0;
"""));
}
}