Application security policy

Enforcing an Application Security Policy can be done in various ways, the most common way of declaring a security management policy is by the usage of the standard SecurityManager class.

For the sake of ROM footprint optimization, permission checks calls are disabled by default to avoid extra code processing if the system owner does not want to use the Security Manager. In order to activate this feature the Option(checkbox): Enable SecurityManager checks option must be set.

Once the security manager checks are enabled, you can then implement your own policy.

To apply a security policy, in the Kernel boot sequence, instantiate a SecurityManager and register it with System.setSecurityManager(SecurityManager) method.

// create an instance of SecurityManager
SecurityManager sm = new SecurityManager() {
   @Override
   public void checkPermission(java.security.Permission perm) {
      // implement here the Application Security Policy
   };
};
// set the Security Manager
System.setSecurityManager(sm);

The sections below document how to implement such policy.

Ready-to-use policy managers

Ready-to-use policy managers are provided by the KF-Util library (since 2.8.0): the “Kernel Security Policy Manager” and the “Kernel Security Manager”.

Note

An example of integration of the latter is available in the Kernel-GREEN project on GitHub.

Kernel Security Policy Manager

This implementation is inspired from the JavaSE JDK Policy File Syntax.
Applications come with a policy resource file that describes the permissions they need at runtime.
By default, the path and the name of this file should be /feature.policy.json. It can be configured using the system property feature.policy.name.
The permission file is loaded when the application is installed.
It assumes the application (and its permissions file) has been approved beforehand.
Typically, the permission file being part of the application binary, this can be verified by signing the application binary and checking the signature at installation.
Finally, the Kernel Security Policy Manager is responsible for checking if the permission has been granted to the calling Application on permission checks requested by the system libraries or not in which case it throws a SecurityException.
Here is a schema to describe the entire flow of the Kernel Security Policy Manager from a feature install to a feature stop.
../_images/kernelSecurityPolicyManagerFlow.png

This implementation requires a parsing of the feature policy file to create the correct list of FeaturePolicyPermission objects that will be handled by the security manager. the KF-Util module provides a JSON implementation for the file format as the default implementation.

This can be done by creating a class that implements the SecurityPolicyResourceLoader interface.

Note

To log every authorized access, change the logger level to FINE in the Kernel system properties such as .level=FINE.

Before going further we strongly advise to take a look to the java.security.Permission Javadoc to fully understand the way permissions work (name, action…).

Here is an example of what a JSON file looks like with placeholders:

{
  "permissions": {
    "<permissionClassName1>":{
      "<permissionName1>":["<permissionAction1>","<permissionAction2>"],
      "<permissionName2>":["<permissionAction1>"]
    },
    "<permissionClassName2>":{
      "<permissionName3>":["<permissionAction3>"]
    }
  }
}

Here is now an example of what a real JSON file can look like:

{
  "permissions": {
    "ej.microui.display.DisplayPermission":{
      "*":[]
    },
    "ej.microui.event.EventPermission":{
      "null":["null"]
    },
    "ej.microui.display.FontPermission":{},
    "ej.microui.display.ImagePermission":{
      "null":["*"]
    },"ej.microui.MicroUIPermission":{
      "*":["start"]
    },"java.net.SocketPermission":{
      "www.microej.com":["connect","resolve"]
    },"java.util.PropertyPermission":{
      "property":["write","read"]
    },"java.lang.RuntimePermission":{
      "exit":[]
    }
  }
}

Note

The permission name attribute is specific to the permission implementation therefore, each permission has its own definition of what a name is.

The parser contains two key words to allow more flexibility over the content of the file:

  • “*”: the wildcard symbol means “any”. It can be used for permission class name, permission name and permission actions.
  • “null”: the null keyword represents a Java null value. It can be used for permission name and permission actions.

To simplify the file structure you can also choose to have an empty object value for permission className or/and permission actions such as shown in the example above:

{
  "permissions": {
    "ej.microui.display.DisplayPermission":{
      "*":[]
    },
    "ej.microui.display.FontPermission":{},
    "java.lang.RuntimePermission":{
      "exit":[]
      }
    }
}

This example:

  • allows the usage of any permission name and any actions for the ej.microui.display.DisplayPermission permission.
  • allows the usage of any permission name and any actions for the ej.microui.display.FontPermission permission.
  • allows the exit permission name and any actions for the java.lang.RuntimePermission permission.

Using an empty value or the * wildcard is left to the developer preference and should be processed in the exact same way by the security policy resource loader.

Warning

If the Kernel does not embed all class names (see Stripping Class Names from an Application), make sure that specified permission class names are embedded by declaring them as Required Types. Any permission check done on a permission class without embedded name will result in a SecurityException.

Kernel Security Manager

This implementation is based on the creation of FeaturePermissionCheckDelegate to specify the behavior of the SecurityManager.checkPermission(Permission) for each permission class.
If a permission check is done and no delegate for its permission is found, a SecurityException is thrown.
An example of this policy manager is used by the Kernel-GREEN.
The policy grants all applications the permission for a list of permission classes and logs all protected accesses by Applications.