Java Routine Security

Java routines

Java routines are SQL external functions and procedures implemented by the application in Java. Allowing creation of Java routines gives rise to some security concerns as it provides the ability for a remote client to execute arbitary Java code on the server. This page defines what the security holes are and the mechanisms (current or future) to close them.

Class categories

A class loaded directly or indirectly by a Java routine can come from one of five locations:

Location

Description

JRE

Classes provided by the JRE - Derby assumes any class in the java. and javax. namespaces are in this category

CP

Classes accessible through standard Java classloading (CLASSPATH, parent class loader, thread context class loader). Note that the contents of the classes available in this group may be unknown to a remote cracker, but potentially could gain clues from stack traces etc.

DBCP

Classes in installed jar files that are listed in derby.database.classpath. Permission add a class into this set is by controlled EXECUTE permission on the procedure to set a database property and the SQLJ procedures. Initially only the database owner has permission to execute these SQLJ procedures.

SQLJAR

Classes in an installed jar file that is not listed in derby.database.classpath. Permission to install, replace or remove a jar file is controlled by EXECUTE permission on the SQLJ procedures. Initially only the database owner has permission to execute the SQLJ procedures.

DERBY

Classes in derby.jar and derbynet.jar. A special case of CP since the Derby classes will be known to be on the classpath and they are open source, which means that a cracker could have studied them for potential security holes.

Resolving Classes

A mapping that shows where a class referenced directly or indirectly by a routine can be loaded from.

EXTERNAL NAME 'package.class.method[(signature)]'

The only way routines can currently be defined in Derby. The defined method in the EXTERNAL NAME clause maps to a public static Java method in a public class. Non-standard (from SQL Part 13 point of view) but supported by multiple databases. Basic security risk is that there is no control or limitation over which Java methods the routine can be defined against.

Entry Point class

The class specified in the EXTERNAL NAME clause can be resolved as:

Location

Resolve

Visibility

JRE

YES

Call any public static method in a public class provided by the JRE

CP

YES

Call any public static method in a public class on the classpath.

DBCP

CONTROLLED (by database owner)

Call any public static method in a public class in the installed jar files on the database classpath.

SQLJAR

NO

none, jar not visible.

DERBY

YES

Call any Derby engine or network class public static method.

When a Security Manager is installed public static method can not directly access any resource (e.g. java.lang.System.exit, System.getProperty) since Derby generates code to execute a SQL statement that calls a routine and that generated code has no permissions granted to it.

Referenced Classes

The EXTERNAL NAME clause defines an entry point for the routine. If the class containing the static method is in an installed jar on the database class path file then that class may reference other classes as follows:

Location

Resolve

Visibility

JRE

YES (required)

Access any class provided by the JRE

CP

YES

Access any class available on the classpath.

DBCP

CONTROLLED (at the database level by database owner)

Access any class available on the database classpath.

SQLJAR

NO

none, jar not visible.

DERBY

YES

Access any Derby engine or network class

When a Security Manager is installed access to any resource requiring Java policy permissions is controlled by the system owner through the policy file. Code can only access resources if the policy file allows and the resource is accessed in a privileged block. Granting permissions to an installed jar file can not be done through a code source URL since Derby does not provide a URL for an installed jar. It can be granted to the code if the installed jar is signed.

EXTERNAL NAME 'jarid:package.class.method[(signature)]' (FUTURE)

Potential enhancement to Derby following the SQL Standard, increases security by specifying which installed jar file the class must come from and USAGE on jars is controlled by GRANT/REVOKE.

Entry Point class

The class specified in the EXTERNAL NAME clause can be resolved as:

Location

Resolve

Visibility

JRE

NO

none, only resolve to class in specified jar.

CP

NO

none, only resolve to class in specified jar.

DBCP

NO

none, only resolve to class in specified jar.

SQLJAR

CONTROLLED (requires USAGE on jar to create routine)

Call any public static method in the specified installed jar

DERBY

NO

none, only resolve to class in specified jar.

Referenced Classes

The accessible classes for a class within an installed jar (not on the database classpath) is limited to the installed jar itself, its optional classpath and the JVM classes. The installed jar's optional classpath is set by the procedure SQLJ.ALTER_JAVA_PATH.

Location

Resolve

Visibility

JRE

YES (required)

Access any class provided by the JRE

CP

NO

none, only resolve to class in specified jar or its classpath.

DBCP

NO

none, only resolve to class in specified jar or its classpath.

SQLJAR

CONTROLLED (requires USAGE on any jar listed in jar's classpath)

Access any class in the specified installed jar or its classpath

DERBY

NO

none, only resolve to class in specified jar or its classpath.

When a Security Manager is installed access to any resource requiring Java policy permissions is controlled by the system owner through the policy file. Code can only access resources if the policy file allows and the resource is accessed in a privileged block. Granting permissions to an installed jar file can not be done through a code source URL since Derby does not provide a URL for an installed jar. It can be granted to the code if the installed jar is signed.

Permissions required to install a jar

All of these permissions must exist before a user can install (or replace) a jar.

Note that this is not possible when a security manager is installed in 10.2 or earlier releases dues to DERBY-537 (fixed in trunk).

Setting derby.database.classpath

Permission to set database classpath is limited by the permission to execute SYSCS_UTIL.SET_DATABASE_PROPERTY. No restriction is placed on which jar files can be added to the database classpath.

In terms of the functionality described by SQL Standard Part 13 setting the database classpath is analogous to:

The analogy breaks down when a class exists in multiple installed jars. E.g. assume an entry point class references a class Next and Next exists in multiple jars on derby.database.classpath. With Derby Next will be resolved from the first jar in derby.database.classpath. With the SQL Standard rules Next would first be resolved from the jar the entry point came from. Thanks to Rick Hillegas for pointing this out.

Potential Security Risks

Assumptions

Security with 10.2, 10.1 and 10.0

Based upon the assumptions:

Limitations

Risks

Security with 10.3 onwards

Based upon the assumptions and assuming DERBY-537 (already fixed) and DERBY-2040 will be fixed.

Limitations

None.

Risks

Improving Java Routine Security in 10.3 onwards

Discussion and issue tracking is under DERBY-2206. To reduce the potential security risks these steps could be taken:

What

Jira

Description

These reduce security vulnerabilities and allow behaviour to match 10.2

Implement GRANT USAGE on jar files

Follow SQL Standard Part 13

Restrict jars added to derby.database.classpath

Require that an installed jar must have USAGE granted to PUBLIC before it can be added to the derby.database.classpath. (Simple alternative: installed jar is ignored in classpath unless it has USAGE granted to PUBLIC). Explicit change in behaviour from 10.2 to improve security

Only expose Derby's api

DERBY-467

Disallow any routine or classes loaded from an installed jar to reference any class in the namespace org.apache.derby. unless it is part of Derby's public api. Reduces the possibility for routines to exploit security bugs in Derby.

Define pseudo jar SYS.CLASSPATH

Jar name that represents the classpath (CP), requires USAGE to be granted like any other jar, by default USAGE is only granted to the database owner. This provides controlled access to code on the classpath. If SYS.CLASSPATH is granted to PUBLIC then it is implicitly included in derby.database.classpath as in 10.2. Explicit change in behaviour from 10.2 to improve security

Define pseudo jar SYS.JRE

Jar name that represents the JRE classes. Creating a routine that directly uses a JRE public static method would require USAGE to be granted on this jar. Note that since JRE usage must be supported when resolving from an installed jar SYS.JRE behaves differently to other jars. If SYS.JRE is granted to PUBLIC then it is implicitly included in derby.database.classpath as in 10.2. This does not close the vulnerability to JREBUGs through malicious code in installed jars, because Java code needs access to the standard Java libraries. Explicit change in behaviour from 10.2 to improve security

These provide additional functionality for Java routines

Support jarid in EXTERNAL NAME

Allows users to create their own routines without exposing their code to all users. Require to implement class loading that is resticted to the given jar even for referenced classes. Without this then the only useful USAGE grant on an installed jar is one to PUBLIC.

Implement SQLJ.ALTER_JAVA_PATH

Allows installed jars to reference multiple jars routine entry point is defined with a jar id

Example Attacks

Accessing database files directly

Accessing the database files directly thus bypassing database level security in order to read or modify a table one does not have access to.

Denial of service attacks

Denial of service attacks such as shutting down the JVM

JavaRoutineSecurity (last edited 2009-09-20 22:12:00 by localhost)