Method Invocation Authorizers
Overview
When the SecurityManager
is enabled, by default Geode throws a NotAuthorizedException
when a method
within a query is invoked and does not belong to the list of default allowed methods, given in RestrictedMethodAuthorizer.
The MethodInvocationAuthorizer
is used to determine whether a specific method invocation on a given object should be allowed or denied during the execution of a particular OQL query.
Allowing users to execute arbitrary methods on any object present within the Geode member’s classpath could impact the integrity of the data and the system on which Geode is running.
In order to avoid this problem, it is always recommended to enable a SecurityManager
at the cluster level, give users only the permissions they require, and configure a MethodInvocationAuthorizer
that meets your needs.
The main threats to which a Geode cluster might be exposed without a MethodInvocationAuthorizer
are highlighted below.
Java Reflection
Allows the user to do anything within the JVM.
SELECT * FROM /region r WHERE r.getClass().forName('java.lang.Runtime').getDeclaredMethods()[0].invoke()
Cache Modification
Allows the user to do anything with the Cache
: close it, access other regions, etc.
SELECT * FROM /region.getCache().close()
Region Modification
Allows the user to destroy, add or invalidate the entire Region
, or specific entries
.
SELECT * FROM /region.destroyRegion()
SELECT * FROM /region.put('xyz','abc')
SELECT * FROM /region.invalidate('xyz')
Region Modification
Allows the user to mutate the state of specific entries
.
`SELECT r.setName('newName') FROM /region r` |
Geode Authorizers
Geode provides four authorizers out of the box, each one designed and implemented for a specific use case in mind. It is recommended to always use one of these authorizers, and only implement your own if your use case needs are not already met by one of them.
All of the implementations provided by Geode are designed to prevent security problems and have been thoroughly tested. Extra care should be taken, however, when configuring the internals of some of the authorizers as an incorrect configuration might introduce security holes into the system.
The table below shows a summary of which security threats are fully addressed by each authorizer and which ones might be exploitable, depending on how they are configured (details are shown later for each implementation).
RestrictedMethodAuthorizer
The default MethodInvocationAuthorizer
used by Geode to determine whether a method is allowed to be executed on a specific object instance or not.
The implementation forbids the invocation of all methods during a query execution, except for the ones shown below:
Class | Allowed Methods |
---|---|
java.lang.Object |
equals , toString , compareTo |
java.lang.Boolean |
booleanValue |
java.lang.Number |
byteValue , intValue , doubleValue , floatValue , longValue , shortValue |
java.util.Date |
after , before , getTime |
java.sql.Timestamp |
getNanos |
java.lang.String |
chartAt , codePointAt , codePointBefore , codePointCount , compareToIgnoreCase , concat , contains , contentEquals , endsWith , equalsIgnoreCase , getBytes , hashCode , indexOf , intern , isEmpty , lastIndexOf , length , matches , offsetByCodePoints , replace , replaceAll , replaceFirst , split , startsWith , substring , toCharArray , toLowerCase , toUpperCase , trim |
java.util.Map.Entry , org.apache.geode.cache.Region.Entry |
getKey , getValue |
java.util.Collection , java.util.Map , org.apache.geode.cache.Region |
get , entrySet , keySet , values , getEntries , getValues , containsKey |
The authorizer also provides utilities that can be used by custom implementations to determine whether a method is permanently forbidden or, if the method belongs to Geode, whether it is considered safe to be used within a query execution.
The methods getClass
, readObject
, readResolve
, readObjectNoData
, writeObject
and writeReplace
are permanently forbidden.
The below table shows those methods that belong to Geode and are considered safe (for methods on org.apache.geode.cache.Region
, the authorizer also verifies that the user has the DATA:READ:RegionName
permission).
Class | Allowed Methods |
---|---|
org.apache.geode.cache.Region.Entry |
getKey , getValue |
org.apache.geode.cache.Region |
get , entrySet , keySet , values , getEntries , getValues , containsKey |
UnrestrictedMethodAuthorizer
A less restrictive MethodInvocationAuthorizer
that allows any method invocation during the query execution as long as the following conditions are met:
- The method is not considered permanently forbidden by the RestrictedMethodAuthorizer.
- The method does not belong to Geode, or does belong but is considered safe by the RestrictedMethodAuthorizer.
This authorizer implementation addresses only three of the four main security risks: Java Reflection
, Cache Modification
and Region Modification
.
The Region Entry Modification
security risk still exists: users with the DATA:READ:RegionName
permission will be able to execute ANY method (even those that mutate the object)
on the entries stored within the region and on instances used as bind parameters of the query, so this authorizer implementation must be used with extreme care.
Note: Usage of this authorizer is recommended for secured clusters on which only trusted users and applications have access to the query engine. It might also be used on clusters on which all entries stored are immutable.
JavaBeanAccessorMethodAuthorizer
A more flexible MethodInvocationAuthorizer
that allows methods to be invoked during a query execution if and only if all of the following conditions are met:
- The method is not considered permanently forbidden by the RestrictedMethodAuthorizer.
- The method does not belong to Geode, or does belong but is considered safe by the RestrictedMethodAuthorizer.
- The method follows the design patterns for accessor methods described in the JavaBean Specification 1.01; that is, the method name begins with
is
orget
. - The target object on which the method will be executed belongs to a set of pre-configured packages.
When used as intended, and assuming that all region entries and bind parameters follow the JavaBean Specification 1.01,
this authorizer implementation addresses all four security risks: Java Reflection
, Cache Modification
, Region Modification
and Region Entry Modification
.
It should be noted, however, that the Region Entry Modification
security threat might be re-introduced: users with the DATA:READ:RegionName
privilege will be able to execute any method whose name
starts with is
or get
on the objects stored within the region and on instances used as bind parameters, providing they are in the pre-configured packages. If those methods do not fully follow
the JavaBean Specification 1.01 in that accessors do not mutate the object state, then instances could be potentially modified in place.
Note: Usage of this authorizer is only recommended for secured clusters on which the user has full confidence in that all objects stored within the regions and used as bind parameters follow the JavaBean Specification 1.01. It might also be used on clusters on which all entries stored are immutable.
RegExMethodAuthorizer
A fully flexible MethodInvocationAuthorizer
that allows methods to be invoked during the query execution only if the the following conditions are met:
- The method is not considered permanently forbidden by the RestrictedMethodAuthorizer.
- The method does not belong to Geode, or does belong but is considered safe by the RestrictedMethodAuthorizer.
- The fully qualified method name matches at least one of the pre-configured regular expressions.
When correctly configured, this authorizer implementation addresses the four main security risks: Java Reflection
, Cache Modification
, Region Modification
and Region Entry Modification
.
For the statement to remain true, however, the regular expressions used must be correctly configured so no mutator methods ever match. If the regular expressions are not restrictive enough,
the Region Entry Modification
security risk might be potentially re-introduced: users with the DATA:READ:RegionName
privilege will be able to execute methods (even those modifying the entry) on
the objects stored within the region and on instances used as bind parameters of the query.
Note: This authorizer must be used with extreme care, it is the most powerful in terms of flexibility and versatility (full control through regular expressions regarding what to allow and what to forbid); but it is also the most dangerous as one small mistake in the configured regular expressions can unexpectedly allow a wide variety of non safe methods to be executed.
Note: Usage of this authorizer implementation is only recommended for scenarios in which the user knows exactly what code is deployed to the cluster, allowing a correct configuration of the regular expressions used. It might also be used on clusters on which all entries stored are immutable.
Custom Authorizers
How Authorization Works
It is important to note that the query engine does not have any information about the actual type of the objects while pre-processing or parsing the query itself, neither can it obtain these details before actually executing the query. The actual check to determine whether a method is allowed or not must be executed while the objects are being traversed by the query engine in runtime.
The query engine, however, remembers whether a specific method has been already authorized or not for the current query execution context, meaning that the authorization will be executed only once in the lifetime of a particular query for every new method seen while traversing the objects. Nevertheless, the authorizer implementation must be highly performant as it will be invoked by Geode in runtime during the actual query execution.
Implementing a Method Authorizer
Complete these items to implement a custom method authorizer.
- Decide which methods from your domain model should be allowed to be invoked during a query execution.
- Decide which resources, if any, you will need in order to determine whether a method can be invoked or not.
- Implement the
initialize
method of theMethodInvocationAuthorizer
interface to fully configure your implementation, based on the resources needed to execute the authorization. - Implement the
authorize
method of theMethodInvocationAuthorizer
interface. It must determine whether amethod
is allowed to be executed on a particular object instance during a query execution. The implementation should be lightning fast and thread safe.
Changing the Method Authorizer
You can set the MethodInvocationAuthorizer
to be used by the query engine through the gfsh
command-line utility.
In addition, you can modify the configured MethodInvocationAuthorizer
while members are already running by using the alter query-service command.
It is always advisable to make these changes during periods of low activity, though.
The following constraints apply when the MethodInvocationAuthorizer
used by the cluster is changed in runtime:
- Queries started after the
MethodInvocationAuthorizer
is changed will use the newly configured authorizer. - Queries in flight are not affected. Before the query starts, it picks up the already configured
MethodInvocationAuthorizer
and will use it until the execution finishes. - Indexes configured with an expression using methods forbidden by the newly configured
MethodInvocationAuthorizer
will be marked as invalid the next time a mapping is added or removed from the index. - Continuous queries already running will pick up the newly configured
MethodInvocationAuthorizer
the next time the CQ is processed upon the arrival of a cache event. If the CQ has methods forbidden by the newly configuredMethodInvocationAuthorizer
, any subsequent execution will result in an error during the CQ processing, and theonError
method will be invoked for the associatedCqListener
.
Note: In order to improve performance, the continuous query engine uses an internal cache to avoid executing the query in scenarios for which the answer can be automatically inferred. These results might become invalid after applying the new security rules, so Geode disables the usage of this optimization until the member is restarted or the query is registered again.