public interface JexlPermissions
By specifying or implementing permissions, it is possible to constrain precisely which objects can be manipulated
by JEXL, allowing users to enter their own expressions or scripts whilst maintaining tight control
over what can be executed. JEXL introspection mechanism will check whether it is permitted to
access a constructor, method or field before exposition to the JexlUberspect
. The restrictions
are applied in all cases, for any JexlUberspect.ResolverStrategy
.
This complements using a dedicated ClassLoader
and/or SecurityManager
- being deprecated -
and possibly JexlSandbox
with a simpler mechanism. The NoJexl
annotation processing is actually performed using the result of calling parse(String...)
with no arguments;
implementations shall delegate calls to its methods for NoJexl
to be
processed.
A simple textual configuration can be used to create user defined permissions using
parse(String...)
.
To instantiate a JEXL engine using permissions, one should use a JexlBuilder
and call JexlBuilder.permissions(JexlPermissions)
. Another approach would
be to instantiate a JexlUberspect
with those permissions and call
JexlBuilder.uberspect(JexlUberspect)
.
To help migration from earlier versions, it is possible to revert to the JEXL 3.2 default lenient behavior
by calling JexlBuilder.setDefaultPermissions(JexlPermissions)
with
UNRESTRICTED
as parameter before creating a JEXL engine instance.
For the same reason, using JEXL through scripting, it is possible to revert the underlying JEXL behaviour to
JEXL 3.2 default by calling JexlScriptEngine.setPermissions(JexlPermissions)
with UNRESTRICTED
as parameter.
Modifier and Type | Interface and Description |
---|---|
static class |
JexlPermissions.ClassPermissions
A permission delegation that augments the RESTRICTED permission with an explicit
set of classes.
|
static class |
JexlPermissions.Delegate
A base for permission delegation allowing functional refinement.
|
Modifier and Type | Field and Description |
---|---|
static JexlPermissions |
RESTRICTED
A restricted singleton.
|
static JexlPermissions |
UNRESTRICTED
The unrestricted permissions.
|
Modifier and Type | Method and Description |
---|---|
boolean |
allow(Class<?> clazz)
Checks whether a class allows JEXL introspection.
|
boolean |
allow(Constructor<?> ctor)
Checks whether a constructor allows JEXL introspection.
|
boolean |
allow(Field field)
Checks whether a field explicitly disallows JEXL introspection.
|
boolean |
allow(Method method)
Checks whether a method allows JEXL introspection.
|
boolean |
allow(Package pack)
Checks whether a package allows JEXL introspection.
|
JexlPermissions |
compose(String... src)
Compose these permissions with a new set.
|
static JexlPermissions |
parse(String... src)
Parses a set of permissions.
|
default boolean |
validate(Class<?> clazz)
Checks that a class is valid for permission check.
|
default boolean |
validate(Constructor<?> constructor)
Checks that a constructor is valid for permission check.
|
default boolean |
validate(Field field)
Checks that a field is valid for permission check.
|
default boolean |
validate(Method method)
Checks that a method is valid for permission check.
|
default boolean |
validate(Package pack)
Checks that a package is valid for permission check.
|
static final JexlPermissions UNRESTRICTED
This enables any public class, method, constructor or field to be visible to JEXL and used in scripts.
static final JexlPermissions RESTRICTED
The RESTRICTED set is built using the following allowed packages and denied packages/classes.
Of particular importance are the restrictions on the System
,
Runtime
, ProcessBuilder
, Class
and those on java.net
, java.net
,
java.io
and java.lang.reflect
that should provide a decent level of isolation between the scripts
and its host.
As a simple guide, any line that ends with ".*" is allowing a package, any other is denying a package, class or method.
boolean allow(Package pack)
If the package disallows JEXL introspection, none of its classes or interfaces are visible to JEXL and can not be used in scripts or expression.
pack
- the packageboolean allow(Class<?> clazz)
If the class disallows JEXL introspection, none of its constructors, methods or fields as well as derived classes are visible to JEXL and can not be used in scripts or expressions. If one of its super-classes is not allowed, tbe class is not allowed either.
For interfaces, only methods and fields are disallowed in derived interfaces or implementing classes.
clazz
- the class to checkboolean allow(Constructor<?> ctor)
If a constructor is not allowed, the new operator can not be used to instantiate its declared class in scripts or expressions.
ctor
- the constructor to checkboolean allow(Method method)
If a method is not allowed, it can not resolved and called in scripts or expressions.
Since methods can be overridden and overloaded, this also checks that no superclass or interface explicitly disallows this methods.
method
- the method to checkboolean allow(Field field)
If a field is not allowed, it can not resolved and accessed in scripts or expressions.
field
- the field to checkstatic JexlPermissions parse(String... src)
In JEXL 3.3, the syntax recognizes 2 types of permissions:
Wildcards specifications determine the set of allowed packages. When empty, all packages can be used. When using JEXL to expose functional elements, their packages should be exposed through wildcards. These allow composing the volume of what is allowed by addition.
Restrictions behave exactly like the NoJexl
annotation;
they can restrict access to package, class, inner-class, methods and fields.
These allow refining the volume of what is allowed by extrusion.
# allow a very restricted set of base classes java.math.* java.text.* java.util.* # deny classes that could pose a security risk java.lang { Runtime {} System {} ProcessBuilder {} Class {} } org.apache.commons.jexl3 { JexlBuilder {} }
.*
.;
, a method composed of
its Java name suffixed with ();
. Constructor restrictions are specified like methods using the
class name as method name.All overrides and overloads of a constructors or method are allowed or restricted at the same time, the restriction being based on their names, not their whole signature. This differs from the @NoJexl annotation.
# some wildcards java.lang.*; # java.lang is pretty much a must have my.allowed.package0.* another.allowed.package1.* # nojexl like restrictions my.package.internal {} # the whole package is hidden my.package { class0 { class1 {} # the whole class1 is hidden class2 { class2(); # class2 constructors can not be invoked class3 { aMethod(); # aMethod can not be called aField; # aField can not be accessed } } # end of class2 class0(); # class0 constructors can not be invoked method(); # method can not be called field; # field can not be accessed } # end class0 } # end package my.package
src
- the permissions source, the default (NoJexl aware) permissions if nullJexlPermissions compose(String... src)
This is a convenience method meant to easily give access to the packages JEXL is
used to integrate with. For instance, using
would extend the restricted set of permissions by allowing the com.my.app package.RESTRICTED
.compose("com.my.app.*")
src
- the new constraintsdefault boolean validate(Package pack)
pack
- the packagedefault boolean validate(Class<?> clazz)
clazz
- the classdefault boolean validate(Constructor<?> constructor)
constructor
- the constructordefault boolean validate(Method method)
method
- the methodCopyright © 2001–2022 The Apache Software Foundation. All rights reserved.