Security Considerations for JScript
Writing secure code is a challenge in any language. JScript includes a few areas where developers might unknowingly use the language in an insecure way because the language does not force developers to use the most effective practices. Although JScript has been designed with security as a goal, its primary goal is to promote rapid development of useful applications. In some cases, these two goals are in opposition.
You can avoid security issues if you are aware of the potential problems in several key areas that are listed below. These security considerations, except the eval method, are due to the new functionality that the .NET Framework introduces.
The most easily misused feature of JScript is the eval method, which allows the dynamic execution of JScript source code. Because a JScript application that uses the eval method may execute any code that a program passes to it, every call to the eval method poses a security risk. Unless your application requires the flexibility of executing any code, consider explicitly writing the code that the application passes to the eval method.
To increase the security of applications that require the full flexibility provided by the eval method, the code passed to eval runs within a restricted context by default. The restricted security context helps prevent all access to system resources, such as the file system, the network, or the user interface. A security exception is generated if the code attempts to access those resources. However, code run by the eval method can still modify local and global variables. For more information, see eval Method.
Code written in previous versions of JScript may require the eval method to run code in the same security context as the calling code. To enable this behavior, you can pass the string "unsafe" as the optional second parameter to the eval method. You should execute only code strings obtained from well-known sources because in "unsafe" mode the code string executes with the same permissions as the calling code.
The security attributes of the .NET Framework can be used to explicitly override the default security settings in JScript. However, the security defaults should not be modified unless you know exactly what you are doing. In particular, one thing that you should not apply is the AllowPartiallyTrustedCallers attribute (APTCA) custom attribute because untrusted callers cannot safely call JScript code, in general. If you create a trusted assembly with APTCA that is then loaded by an application, a partially trusted caller could access fully trusted assemblies in the application. For more information, see Secure Coding Guidelines.
The engine which hosts JScript allows any called code to modify parts of the engine, such as global variables, local variables, and prototype chains of any object. In addition, any function can modify the expando properties or methods of any expando object passed to it. Consequently, if a JScript application calls partially trusted code or if it is running in an application with other code (such as from within a Visual Studio for Applications [VSA] host), the behavior of the application could be modified.
A consequence of this is that any JScript code in an application (or in an instance of an AppDomain class) should run at a trust level no higher than the rest of the code in the application. Otherwise, the other code could manipulate the engine for the JScript class, which could in turn modify data and affect the other code in the application. For more information, see _AppDomain.
JScript can reference assemblies using both strong names and simple text names. A strong name reference includes the version information of the assembly as well as a cryptographic signature that confirms the integrity and identity of the assembly. Although it is easier to use a simple name when referring to an assembly, a strong name helps to protect your code in case another assembly on your system has the same simple name but different functionality. For more information, see How to: Reference a Strong-Named Assembly.
The JScript runtime is not designed to be thread-safe. Consequently, multithreaded JScript code may have unpredictable behavior. If you develop an assembly in JScript, keep in mind that it may be used in a multithreaded context. You should use classes from the System.Threading namespace, such as the Mutex class, to ensure that the JScript code in the assembly runs with the proper synchronization.
Because proper synchronization code is difficult to write in any language, you should not attempt to write general-purpose assemblies in JScript unless you have a good understanding of how to implement the necessary synchronization code. For more information, see System.Threading.
You do not need to write synchronization code for ASP.NET applications written in JScript because ASP.NET manages the synchronization of all the threads it spawns. However, Web controls written in JScript must contain synchronization code because they behave like assemblies.
Because JScript is a loosely typed language, it is more tolerant of potential type-mismatches than some other languages, such as Visual Basic and Visual C#. Because type mismatches can cause run-time errors in applications, it is important to discover potential type mismatches as you develop the code. You can use the /warnaserror flag with the command-line compiler or the warninglevel attribute of the @ Page directive in ASP.NET pages. For more information, see /warnaserror and @ Page.
Assemblies complied in compatibility mode (with the /fast- option) are less encrypted than those compiled in fast mode (the default mode). The /fast- option enables language features that are not available by default, but are required for compatibility with scripts written for JScript version 5.6 and earlier. For example, expando properties can be dynamically added to intrinsic objects, such as the String object, in compatibility mode.
Compatibility mode is provided to help developers build standalone executables from legacy JScript code. When developing new executables or libraries, use default mode. Not only does this help protect applications, but it also helps provide better performance and better interaction with other assemblies. For more information, see /fast.