Sandbox

Another useful feature of #Script is that it operates within a controlled sandbox where each ScriptContext instance is isolated and defines the entire execution environment on which scripts are executed within as such it should be safe to run scripts from untrusted 3rd Party sources as they're confined to what's available within their allowed ScriptContext instance.

ScriptContext

By default the only functionality and objects #Script has access to is what's pre-configured within a new ScriptContext instance which has access to Default Scripts, HTML Scripts and default Script Blocks. #Script can't call methods on instances or have any other way to invoke a method unless it's explicitly registered.

To give additional functionality to your Scripts extend the ScriptContext that executes your script with additional:

Protected Scripts

When running in a trusted contexts like Server Scripts in #Script Pages, scripts have elevated privileges with access to Protected Scripts, ServiceStack and Info Scripts, Bootstrap Scripts and ServiceStack Blocks.

Protected Scripts allows your Scripts to escape the default sandbox and create new instances on existing .NET Types, populate them and call their methods as documented in Scripting .NET. There are 2 levels of access available:

Script Assemblies and Types

You can limit which Types are scriptable by specifying just the individual Types:

var context = new ScriptContext {
    ScriptMethods = {
        new ProtectedScripts()
    },
    ScriptTypes = {
        typeof(MyType),
        typeof(MyType2),
    }
}.Init();

Or you can use ScriptAssemblies to allow scripting of all Types within an Assembly:

var context = new ScriptContext {
    ScriptMethods = {
        new ProtectedScripts()
    },
    ScriptAssemblies = {
        typeof(MyType).Assembly,
    }
}.Init();

AllowScriptingOfAllTypes

To give your Scripts maximum accessibility, you can give them access to all .NET Types in loaded assemblies:

var context = new ScriptContext {
    ScriptMethods = {
        new ProtectedScripts()
    },
    AllowScriptingOfAllTypes = true,
    ScriptNamespaces = {
        typeof(MyType).Namespace,
    }
}.Init();

Use ScriptNamespaces to include additional Lookup namespaces for resolving Types similar to C# using statements.

See Scripting .NET for how to access .NET Types in #Script.

Running untrusted Scripts

If running a script from an untrusted source we recommend running them within a new ScriptContext instance so they're kept isolated from any other ScriptContext instance. Context's are cheap to create, so there won't be a noticeable delay when executing in a new instance but they're used to cache compiled lambda expressions which will need to be recreated if executing script in new ScriptContext instances. For improved performance you can instead have all untrusted templates use the same ScriptContext instance that way they're able to reuse existing caches and compiled expressions.

Remove Default Scripts

If you want to start from a clean slate, the default scripts can be removed by clearing the ScriptMethods collection:

context.ScriptMethods.Clear();

Disabling adhoc Filters

Or if you only want to disable access to some filters without removing them all, you can disable access to adhoc filters by adding to the ExcludeFiltersNamed collection:

var context = new ScriptContext {
    ExcludeFiltersNamed = { "partial", "selectPartial" }
}.Init();
Script Methods can also be disabled on an individual PageResult by populating its ExcludeFiltersNamed collection.

Instance creation and MaxQuota

The only instances that can be created within scripts are what's allowed in JavaScript Literals and the Generation and Repeating Filters. To limit any potential CPU and GC abuse any default scripts that can generate instances are limited to a MaxQuota of 10000 iterations. This quota can be modified with:

var context = new ScriptContext {
    Args = {
        [ScriptConstants.MaxQuota] = 1000
    }
}.Init();

Max Stack Depth

To prevent user-defined functions from causing out of memory Exceptions its execution is limited to a Maximum Stack Depth which can be configured with:

ScriptConfig.MaxStackDepth = 25; //default

made with by ServiceStack