using ZB.MOM.WW.ScadaBridge.ScriptAnalysis; namespace ZB.MOM.WW.ScadaBridge.InboundAPI; /// /// InboundAPI-005: Enforces the ScadaBridge script trust model on inbound API method /// scripts before they are compiled into executable handlers. /// /// This class is now a thin shim that delegates to the shared, authoritative /// implemented in /// ZB.MOM.WW.ScadaBridge.ScriptAnalysis (M3.4). The unified validator runs /// both a semantic symbol pass (catching alias / global:: / using static /// escapes) and the reflection-gateway + dynamic / Activator syntactic /// hardening that previously lived exclusively in this file. /// /// /// InboundAPI-015: a purely namespace-textual deny-list is bypassable because /// reflection is reachable through members of permitted types that never /// spell a forbidden namespace, e.g. /// typeof(string).Assembly.GetType("System.IO.File"). The shared validator /// handles this with both semantic resolution and reflection-gateway member /// hardening — GetType, Assembly, GetMethod, InvokeMember, /// CreateInstance, and the dynamic keyword are all rejected. This /// remains hardening of a best-effort static check, not a true sandbox /// (see the security notes in code-reviews/InboundAPI/findings.md, /// InboundAPI-015). The check is defence-in-depth; genuine containment needs a /// runtime boundary (restricted AssemblyLoadContext / curated reference set / /// out-of-process sandbox). /// /// public static class ForbiddenApiChecker { /// /// Analyses the script source and returns the list of trust-model violations. /// An empty list means the script is acceptable. /// /// The C# script source to analyse. /// A list of trust-model violation messages; empty if the script is clean. public static IReadOnlyList FindViolations(string scriptCode) { if (string.IsNullOrWhiteSpace(scriptCode)) return Array.Empty(); return ScriptTrustValidator.FindViolations(scriptCode); } }