...
RestrictedMethodAuthorizer
GeodeBasedMethodAuthorizer
GeodeMethodAuthorizer
RegexBasedMethodAuthorizer
RegExMethodAuthorizer
JavaBeanAccessorBasedMethodAuthorizer
JavaBeanAccessorMethodAuthorizer
The RestrictedMethodAuthorizer
will be the authorizer used by default out of the box, as it contains the list of methods per object type that are currently considered safe and it also prevents any possible re-introduction of CVE-2017-9795.
The GeodeBasedMethodAuthorizer
GeodeMethodAuthorizer
will basically allow any method execution as long as the target object does not belong to a Geode package or, if it does belong to a geode package, it's considered safe (sub-set of methods already allowed by the RestrictedMethodAuthorizer
). The other two authorizers will always delegate to RestrictedMethodAuthorizer
and expand the set of allowed methods with whatever the internal implementation is configured to do. The JavaBeanAccessorBasedMethodAuthorizer
JavaBeanAccessorMethodAuthorizer
covers the most common use cases and requires little to no configuration effort. For those use cases not covered, the users can choose to use the RegexBasedMethodAuthorizer
RegExMethodAuthorizer
, which allows them to configure which methods to allow directly through regex expressions. If none of the above is a good fit for a particular situation, the user ultimately has the option to provide its own implementation of the MethodInvocationAuthorizer
interface and do whatever needed in order to allow/deny the execution of particular methods.
...
Authorizer \ Threat | Reflection | Cache Access | Region Access | Entry Modification |
---|---|---|---|---|
RestrictedMethodAuthorizer | ||||
GeodeBasedMethodAuthorizerGeodeMethodAuthorizer | ||||
RegexBasedMethodAuthorizerRegExMethodAuthorizer | ||||
JavaBeanAccessorBasedMethodAuthorizerJavaBeanAccessorMethodAuthorizer |
Implementation Details
This section is just an overview and it contains some ideas of how the proposal could be achieved, no PoC has been done so far so the implementations details might change.
draw.io Diagram | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Interface MethodInvocationAuthorizer (Public)
...
- Too restrictive .
- User can't use methods in queries .
- User can't use non-public fields in queries as the implicit method invocation is also denied .
...
GeodeMethodAuthorizer
Allow any method execution as long as the target object does not belong to a Geode package, or does belong but it's marked as safe (Region.get, Region.entrySet, Region.keySet, Region.values, Region.getEntries, Region.getValues, Region.containsKey, Region.getKey
and Region.getValue
). Some known dangerous methods (like getClass
) will also be rejected, no matter whether the target object belongs to a Geode package or not. The implementation will be immutable and thread-safe.
...
- In place modifications are allowed .
- Users with
DATA:READ:RegionName
privileges can modify the entries within the region through methods that mutate the object, thus part of CVE-2017-9795 can be re-introduced .
...
RegExMethodAuthorizer
Methods allowed to be executed should match some regex expression(s) configured by the user, similar to what we currently do today with the PDX ReflectionBasedAutoSerializer
. The implementation will have an internal structure containing already compiled Pattern
instances and use them to verify the actual method that should be executed by the OQL engine, denying or allowing the execution based on the match result. If there is no match, it will delegate the final decision to the RestrictedMethodAuthorizer
. The implementation will be immutable and thread-safe.
...
- Performance impact .
- Customers still need to configure “something” (the regex) .
- Customers need to learn regex expressions, if they don't do already .
- Operators with little Regex knowledge can accidentally allow everything depending on which wildcards are used and, thus, reintroduce part of CVE-2017-9795 .
...
JavaBeanAccessorMethodAuthorizer
Allow the OQL engine to execute any method that follows the design patterns for accessor methods described in the JavaBean specification 1.01; that is, basically, allow any method starting with get
or is
. For extra security, only methods belonging to classes under certain packages (configured by the user) should be allowed, and some known dangerous methods (like getClass
) should be disabled. If there is no match, it will delegate the final decision to the RestrictedMethodAuthorizer
. The implementation will be immutable and thread-safe.
...
# Customer deploys the jar and configures the GeodeBasedMethodAuthorizer GeodeMethodAuthorizer
$> deploy --jar=/tmp/model-1.0.0.jar
$> alter query-service --method-authorizer=GeodeBasedMethodAuthorizerGeodeMethodAuthorizer
# All classes follow the JavaBean specification 1.01 for accessor methods
# Customer deploys the jar and configures the JavaBeanAccessorBasedMethodAuthorizer JavaBeanAccessorMethodAuthorizer
$> deploy --jar=/tmp/model-1.0.0.jar
$> alter query-service --method-authorizer=JavaBeanAccessorBasedMethodAuthorizerJavaBeanAccessorMethodAuthorizer{'packages' : 'order.model,tickets.model'}
...
# Customer deploys the jar and configures the JavaBeanAccessorBasedMethodAuthorizer JavaBeanAccessorMethodAuthorizer
$> deploy --jar=/tmp/model-1.0.0.jar
$> alter query-service --method-authorizer=JavaBeanAccessorBasedMethodAuthorizerJavaBeanAccessorMethodAuthorizer{'packages' : 'order.model,tickets.model'}
...
# These methods need to be accessed through OQL right away in production, so they configure RegexBasedMethodAuthorizer RegExMethodAuthorizer with the required regex to allow default java bean accessors (get*|is*) + methods starting with "calculate*"
alter query-service --method-authorizer=RegexBasedMethodAuthorizerRegExMethodAuthorizer{'patterns' : 'model.*(get|is|calculate)'}
...
# After removing all "calculateXXXX" methods the customer deploys the new model and re-configures the JavaBeanAccessorBasedMethodAuthorizerJavaBeanAccessorMethodAuthorizer
deploy --jar=/tmp/model-2.0.0.jar
alter query-service --method-authorizer=JavaBeanAccessorBasedMethodAuthorizerJavaBeanAccessorMethodAuthorizer{'packages' : 'order.model,tickets.model'}
...
The primary problem with these solutions is that they force the user to modify the domain model and, also, add extra unnecessary coupling. With this proposal, anyway, the user can ultimately use these frameworks by just providing their own authorizer implementation and check the annotation in order to allow/deny the method execution.
Errata
- The contract for the interface
MethodInvocationAuthorizer
won't include athrows
clause for theNotAuthorizedException
class, that exception was designed to indicate that the subject is not allowed to execute a particular operation, not to indicate that a problem has occurred and that the authorization can not be determined. Since Geode can't do anything to recover from such errors and doesn't have any insights about the actual implementation, a non checked exception should be thrown whenever there's an error while executing the authorization logic. - Authorizer Implementations won't have Based as part of the actual name since the word doesn't add anything useful to the class name.