T09 · Insecure Skill Coding Practices
Error
- Location
- COMPILATION_ERROR_HANDLING.md:411
- Finding
- Untrusted C# Scripts Can Be Compiled and Executed with Host Process Privileges<![CDATA[ ## Vulnerability Details **File Location**: `COMPILATION_ERROR_HANDLING.md:411-430` **Vulnerability Type**: Arbitrary in-process code execution **Risk Level**: High ### Vulnerable Code ```csharp public class ScriptEngine { public object Execute(string script) { var builder = new AssemblyCSharpBuilder(); builder.UseRandomLoadContext().UseSmartMode(); NatashaCompilationLog? log = null; builder.CompileFailedEvent += (compilation, errors) => { log = compilation.GetNatashaLog(); }; try { builder.Add(script); var assembly = builder.GetAssembly(); var type = assembly.GetTypes().First(); var method = type.GetMethods().First(m => m.IsStatic && m.IsPublic); return method.Invoke(null, null); } ``` A second example demonstrates the same unsafe trust model for code loaded from files: **Additional Location**: `references/common-patterns.md:929-970` ```csharp public static List<T> ScanLogical<T>(string[] pluginFiles, string fatherClassName) where T : class { List<T> result = []; AssemblyCSharpBuilder assemblyCSharp = new(); assemblyCSharp .UseRandomLoadContext() .UseSmartMode() .WithDebugCompile(c => c.ForAssembly()); var fileIndexArray = new int[pluginFiles.Length]; Dictionary<int, string> typeNamesCache = []; for (int i = 0; i < pluginFiles.Length; i++) { var fileIndexString = Path.GetFileNameWithoutExtension(pluginFiles[i]); if (fileIndexString != null && Int32.TryParse(fileIndexString, out var fileIndex)) { var className = $"N{Guid.NewGuid():n}"; typeNamesCache.Add(fileIndex, className); var classMethodText = File.ReadAllText(pluginFiles[i]); var classScript = @$"public class {className} : {fatherClassName}{{ {classMethodText} ...[truncated 2990 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Explicitly document that these APIs must compile only trusted, administrator-controlled source code. 2. Do not expose raw C# source submission to unauthenticated or untrusted users. 3. If untrusted code execution is unavoidable, move compilation and execution into a separate, disposable process or container. 4. Run that worker under a dedicated least-privileged operating-system identity with: - No access to application secrets. - A read-only or isolated filesystem. - No outbound network access unless explicitly required. - No access to host sockets or privileged devices. - Strict CPU, memory, process, and execution-time limits. 5. Use a narrowly defined IPC contract and validate all inputs and outputs exchanged with the worker. 6. Authenticate and authorize script or plugin submission, retain audit logs, and require integrity verification or signed plugins where appropriate. 7. Treat syntax-tree allowlists only as defense in depth; they are not a replacement for operating-system isolation. 8. Avoid enabling private-member access, unsafe blocks, native interoperability, or broad metadata access for untrusted workloads. ]]>
