Using .NET classes from scripts

One great feature of Jint is to be able to execute any exposed CLR class. During execution, types are resolved by searching over loaded assemblies.

Usage

To access any CLR type, the only requierement is to use the full name of the type. This contraint is explained by the fact that ECMAScript doesn't define any directive like using.

Here is a simple example using StringBuilder instance.

string stringBuilder = @"
    var sb = new System.Text.StringBuilder();
    sb.Append('hi, mom');
    sb.Append(3);	
    sb.Append(true);
    return sb.ToString();
    ";

var result = new JintEngine()
    .Run(stringBuilder));

// hi, mom3True

Generics

Your scripts can instantiate and use generics classes and methods. The usage is the same as in C# instead the types must be declared with the fullname, and enclosed between curly braces '{' and '}'.

var list = new System.Collections.Generic.List{System.Int32}(); 
list.Add(7); list.Add(3); list.Add(4);
list = list.ConvertAll{System.Double}( function (x) { return x * x; });
assert(3, Number(list.Count));
assert(49, list[0]);
assert(9, list[1]);
assert(16, list[2]);

Security

Running such dynamic scripts can rapidly open some security issues. Indeed, if an application is accepting external plugins or behaviors, we have to ensure that these scripts can't be a threat for the local system. Such threats can be access to the file system, use network assets, and so on. .NET comes with a set of features to define those boundaries, namely CAS (Code Access Security).

Jint by default allows the use of .NET types in a Low Trust security context. This means that any .NET type can be used as soon as it's safe. If even this level is too low for you, you can decide to disable any binding with the CLR by setting the AllowClr property to false. If any script attempts to use a CLR type, a System.Security.SecurityException is thrown.

string stringBuilder = @"
    var sb = new System.Text.StringBuilder();
    return sb.ToString();
    ";
var engine = new JintEngine();
engine.AllowClr = false;
engine.Run(stringBuilder); // throws a SecurityException

Most of the time safely using .NET types will be ok. Though you may also want to let the scripts access some specific resources. This can be done by adding specific permissions using any available System.Security.Permissions.IPermission instance. For more information on security permissions, please read http://msdn.microsoft.com/en-us/library/930b76w0.aspx.

This example above shows how to define a specific sand box for allowing a script to write in a specific directory.

string userDirectory = "c:\\temp";

string script = @"
    var b = System.IO.Directory.GetFiles(userDir);
";

var engine = new JintEngine()
    .SetParameter("userDir", userDirectory)
    .AddPermission(new FileIOPermission(FileIOPermissionAccess.PathDiscovery, userDirectory))
    .Run(script);

Several permissions can be defined. You can get a list of all of them on this page: http://msdn.microsoft.com/en-us/library/system.security.permissions.aspx

Disabling Security

If your envrionment is fully trust, you can prevent security exception by disabling it. To do so just call the DisableSecurity() method on the engine.

Last edited Feb 8, 2010 at 1:44 PM by sebastienros, version 4

Comments

Verious Dec 31, 2010 at 5:05 PM 
In .NET 4.0 the security model has changed, most .NET classes that will be added to Jint using the SetParameter() function should be tagged with the SecurityTransparent() attribute to avoid causing an elevation of privileges (unless your class needs a specific permission, such as writing to the file system). See the following example:

// The assembly will be similar to the following:

using System.Security;

[assembly: SecurityTransparent()]
namespace Sample {
public class SampleClass {
public void DoSomething() {
// Do something interesting.
}
}
}

// The application will contain code similar to the following:

SampleClass sample = new SampleClass();
jint.SetParameter("sample", sample);