fix(scripting): block ThreadPool/Timer/AssemblyLoadContext in sandbox
Core.Scripting-012 (High, Security) resolution.
The Core.Scripting-008 rewrite broadened the BCL references list from a
narrow allow-list to the full System.* + netstandard +
Microsoft.Win32.Registry set, delegating the security gate entirely to
ForbiddenTypeAnalyzer. Three categories of dangerous BCL types were
reachable from script source without a deny-list entry:
- System.Threading.ThreadPool — QueueUserWorkItem re-introduces the
background-fanout threat Core.Scripting-003 closed against
System.Threading.Tasks.
- System.Threading.Timer — schedules unbounded callback work that
outlives the per-evaluation timeout.
- System.Runtime.Loader.AssemblyLoadContext — loads arbitrary DLLs.
Defense-in-depth gap; invocation needs reflection (already denied)
but the load itself was reachable.
Fix:
- Added 'System.Runtime.Loader' to ForbiddenNamespacePrefixes
(preferred over type-granular per the recommendation so future BCL
additions to that namespace are denied by default).
- Added 'System.Threading.ThreadPool' and 'System.Threading.Timer'
to ForbiddenFullTypeNames — both live in System.Threading shared
with allowed primitives so they must be type-granular.
Regression tests added to ScriptSandboxTests:
Rejects_ThreadPool_QueueUserWorkItem_at_compile
Rejects_Timer_new_at_compile
Rejects_AssemblyLoadContext_at_compile
Docs:
docs/v2/implementation/phase-7-scripting-and-alarming.md decision #6
and the Sandbox-escape compliance-check row both updated to enumerate
the new entries per the Core.Scripting-009 doc-sync convention.
Two lower-impact suggestions from the finding's recommendation
(System.Console, CultureInfo.DefaultThreadCurrentCulture) were
intentionally not addressed and are recorded as accepted minor risks
in the resolution.
Verification: Core.Scripting.Tests 107/107 (was 104 + 3 new rejection
tests).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
| Review date | 2026-05-23 |
|
||||
| Commit reviewed | `a9be809` |
|
||||
| Status | Reviewed |
|
||||
| Open findings | 4 |
|
||||
| Open findings | 3 |
|
||||
|
||||
## Checklist coverage
|
||||
|
||||
@@ -375,7 +375,7 @@ Warning event.
|
||||
| Severity | High |
|
||||
| Category | Security |
|
||||
| Location | `ForbiddenTypeAnalyzer.cs:60-76`, `ScriptSandbox.cs:96-126` |
|
||||
| Status | Open |
|
||||
| Status | Resolved |
|
||||
|
||||
**Description:** The Core.Scripting-008 rewrite broadened the BCL references list
|
||||
from a narrow allow-list (`System.Private.CoreLib` + `System.Linq` only) to the
|
||||
@@ -443,7 +443,26 @@ mirroring the Core.Scripting-010 vector style. Update
|
||||
"Sandbox escape" compliance-check row to enumerate the additions, per the
|
||||
Core.Scripting-009 doc-sync convention.
|
||||
|
||||
**Resolution:** _(empty until closed; on close, record the fixing commit SHA, the date, and a one-line description of the fix)_
|
||||
**Resolution:** Resolved 2026-05-23 — added `System.Runtime.Loader` to
|
||||
`ForbiddenNamespacePrefixes` (the namespace-prefix form preferred over
|
||||
type-granular per the recommendation; future BCL additions to that namespace
|
||||
are denied by default). Added `System.Threading.ThreadPool` and
|
||||
`System.Threading.Timer` to `ForbiddenFullTypeNames` — both live in
|
||||
`System.Threading` shared with allowed sync primitives so they must be
|
||||
type-granular. Regression tests added to `ScriptSandboxTests`:
|
||||
`Rejects_ThreadPool_QueueUserWorkItem_at_compile`,
|
||||
`Rejects_Timer_new_at_compile`, `Rejects_AssemblyLoadContext_at_compile`.
|
||||
`docs/v2/implementation/phase-7-scripting-and-alarming.md` decision #6 +
|
||||
the Sandbox-escape compliance-check row both updated per the
|
||||
Core.Scripting-009 doc-sync convention. The two lower-impact suggestions
|
||||
from the recommendation (`System.Console`, `CultureInfo.DefaultThreadCurrentCulture`)
|
||||
were intentionally not addressed: `Console.SetOut` requires constructing
|
||||
a `System.IO.TextWriter` which is already blocked, leaving only
|
||||
`Console.WriteLine` log-spam (annoyance, not a security threat); and
|
||||
`CultureInfo.DefaultThreadCurrentCulture` is a cross-script side-effect
|
||||
worth knowing about but doesn't escape the sandbox. Recording both as
|
||||
accepted minor risks. Test totals after fix: Core.Scripting 107 green
|
||||
(was 104 — +3 new rejection tests).
|
||||
|
||||
### Core.Scripting-013
|
||||
|
||||
|
||||
Reference in New Issue
Block a user