JavaScript Security

Introduction

Several components of Elixir Repertoire such as data source and report template may embed Javascript to generate dynamic effects during report rendering.

Javascript is a powerful tool and may perform dangerous actions that will cause undesirable effects if not used properly. As a result, a user may want to control what the scripts can do. For example, javascripts should not be allowed to write any file on the system or establish any network connection to an unknown network.

Elixir Runtime enables to user to set the exact security permissions to the Javascript. This is based on the standard Java Security Architecture. Java platform supports a policy-based, easily configurable and fine-grained access control model. Following this model, security permissions for Javascripts can be specified in a policy file, which is enforced by Java at runtime.

Steps to protect users from malicious Javascripts

  • Find out the requirements of the application's security

  • Configure security permissions given to application, Repertoire Runtime and Javascripts embedded in report templates

  • Run the Java application with Security Manager

  • Verify that security policies are taking effect

To find out the application's security requirements, you will need to check :

  • The security permissions that should be given to the application. Once Security Manager is installed with the Java application, all Java classes are guarded by security policies, including your own codes. Therefore, if the application needs to perform security sensitive operations, you will need to grant those permissions explicitly.

  • The security permissions that should be given to Repertoire's Runtime. Enough permissions should be given so that report templates can be loaded from the file system, write rendered reports to hard disk, etc. successfully.

  • The security permissions that should be given to your Javascripts. This will depend on the functionality of the scripts. For example, if one of the scripts needs to write the output to a file, you might need to grant write permission on the file (to the script) explicitly.

Configure Security Permissions

The Java Security Manager checks a file for security permissions. By default, the file is called "java.policy" under your Java runtime installation folder (${JRE_HOME}/lib/security/java.policy). You can also save your policies in a different file, but you will need to tell Security Manager the location to find the file. The file must follow certain syntax so that Security Manager can work properly.

The policy file in the /config directory of Elixir Repertoire (java2.policy) grants all security permissions to Java classes loaded from /bin, /ext and /lib directory of Elixir Repertoire. These classes are either Repertoire's built-in classes or put in by system administrators, which makes it safe to trust (by default).

In the default policy file, Javascripts written by end users are allowed to :

  • read all Java system properties, such as "java.version"

  • read files in Repertoire installation directory

  • read, write and delete files in OS's temp directory

If the scripts try to do other security related actions (such as writing a system file import for your operating system), your scripts will fail to run and some error logs will be generated.

On Repertoire Report Designer UI, you can view console logs which are generated as you render your reports. Logs are organized into different categories and one of them is "JavascriptLog". When your scripts fail to run for some reason, you can always check this console log to see the reason of failing.

When your script fails because it does not have certain permissions to complete the task, the log entry should look something like : Error evaluating script: java.security.AccessControlException: access denied (<permission required>)

Verify that Security Policies are Taking Effect

The best way to verify security policies is to write some Javascript. Try to do some operations that are not allowed and make sure the script fails.

Here is one short example :

When designing a report template with Repertoire Report Designer, you can insert Javascript in several places. There is one example given in ElixirSamples which dynamically changes the background colour of some text field depending on the value being displayed. The report template used is /ElixirSamples/Report/Scripting/OnRenderBegin.rml.

When you try rendering this template in Glint (without making any changes), the following figure, Figure 6.2, “Generated Report Before Changes”, will be the output.

Figure 6.2. Generated Report Before Changes

Generated Report Before Changes

When the first line of script (as seen in Figure 6.3, “Additional Scripts”) is added to the report, the template generated will be different from the one shown above.

Figure 6.3. Additional Scripts

Additional Scripts

The generated output will be as seen in Figure 6.4, “Generated Report After Changes”.

Figure 6.4. Generated Report After Changes

Generated Report After Changes

In the console, error logs as seen in Figure 6.5, “Error logs in Console” will be captured indicating that the file is unable to write to the system.

Figure 6.5. Error logs in Console

Error logs in Console

This is an expected behavior as the settings in our default policy file (java2.policy) do not allow user scripts to write a file to the system and the script is trying to write a file named "test" into the system.