You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2023/03/10 12:20:06 UTC
[commons-jexl] branch master updated: JEXL: getting ready for 3.3; - javadoc, doc final touches
This is an automated email from the ASF dual-hosted git repository.
henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
The following commit(s) were added to refs/heads/master by this push:
new 36d9f06b JEXL: getting ready for 3.3; - javadoc, doc final touches
36d9f06b is described below
commit 36d9f06bbdced9d4775d5475d9855402988c2b82
Author: henrib <he...@apache.org>
AuthorDate: Fri Mar 10 13:20:00 2023 +0100
JEXL: getting ready for 3.3;
- javadoc, doc final touches
---
RELEASE-NOTES.txt | 10 +-
.../jexl3/introspection/JexlPermissions.java | 31 ++---
src/site/site.xml | 4 +-
src/site/xdoc/index.xml | 126 +++++++++++----------
src/site/xdoc/relnotes33.xml | 7 +-
5 files changed, 90 insertions(+), 88 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 043edcdb..29450e27 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -33,11 +33,9 @@ in breaking your application behavior ; this breaking change requires remediatio
Despite the obvious inconvenience - our sincere apologies on the matter -, how much functional and semantic power is
accessible through scripts has a real impact on your application security and stability ; that potential risk requires
an informed review and conscious choice on your end.
-To mitigate the change, you can revert to the previous behavior with one line of code (see JexlBuilder) or use this
-opportunity to reduce exposure. Whether Files, URLs, networking, processes, class-loaders or reflection features are
-accessible are part of the choice to make.
-Any CVE linked to JEXL should try resolution by upgrading to 3.3.
-
+To mitigate the change, you can revert to the previous behavior with one line of code (see JexlPermissions, JexlBuilder
+and JexlScriptEngine) or use this opportunity to reduce exposure. Whether Files, URLs, networking, processes,
+class-loaders or reflection classes or whether loops or side-effects are accessible are part of your choice to make.
What's new in 3.3:
==================
@@ -45,7 +43,7 @@ JEXL 3.3 brings the ability to configure permissions on libraries in the manner
with the @NoJexl annotation on source code. This is achieved through a crude but light mechanism akin to
a security manager that controls what JEXL can introspect and thus expose to scripts.
Used in conjunction with options (JexlOptions) and features (JexlFeatures), the permissions (JexlPermissions)
-allow fine-tuning the scripting integration into any project.
+allow fine-tuning the end-user freedom and scripting integration through syntactic and semantic sanitation.
JEXL 3.3 also adds some syntactic (ECMAScript) features (let, const, =>, for, ...) to further reduce
the skill set required to write scripts.
diff --git a/src/main/java/org/apache/commons/jexl3/introspection/JexlPermissions.java b/src/main/java/org/apache/commons/jexl3/introspection/JexlPermissions.java
index d405b6cd..3af353ed 100644
--- a/src/main/java/org/apache/commons/jexl3/introspection/JexlPermissions.java
+++ b/src/main/java/org/apache/commons/jexl3/introspection/JexlPermissions.java
@@ -54,7 +54,7 @@ import java.util.stream.Collectors;
* <p>
* To help migration from earlier versions, it is possible to revert to the JEXL 3.2 default lenient behavior
* by calling {@link org.apache.commons.jexl3.JexlBuilder#setDefaultPermissions(JexlPermissions)} with
- * {@link #UNRESTRICTED} as parameter.
+ * {@link #UNRESTRICTED} as parameter before creating a JEXL engine instance.
* </p>
* <p>
* For the same reason, using JEXL through scripting, it is possible to revert the underlying JEXL behaviour to
@@ -142,15 +142,17 @@ public interface JexlPermissions {
* java.lang { Runtime {} System {} ProcessBuilder {} Class {} }
* org.apache.commons.jexl3 { JexlBuilder {} }
* </pre>
- * <p>
- * Syntax for wildcards is the name of the package suffixed by <code>.*</code>. Syntax for restrictions is
- * a list of package restrictions. A package restriction is a package name followed by a block
- * (as in curly-bracket block {}) that contains a list of class restrictions. A class restriction is a class name
- * followed by a block of member restrictions. A member restriction can be a class restriction - to restrict
+ * <ul>
+ * <li>Syntax for wildcards is the name of the package suffixed by <code>.*</code>.</li>
+ * <li>Syntax for restrictions is a list of package restrictions.</li>
+ * <li>A package restriction is a package name followed by a block (as in curly-bracket block {})
+ * that contains a list of class restrictions.</li>
+ * <li>A class restriction is a class name followed by a block of member restrictions.</li>
+ * <li>A member restriction can be a class restriction - to restrict
* nested classes -, a field which is the Java field name suffixed with <code>;</code>, a method composed of
* its Java name suffixed with <code>();</code>. Constructor restrictions are specified like methods using the
- * class name as method name.
- * </p>
+ * class name as method name.</li>
+ * </ul>
* <p>
* 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.
@@ -190,7 +192,8 @@ public interface JexlPermissions {
/**
* Compose these permissions with a new set.
* <p>This is a convenience method meant to easily give access to the packages JEXL is
- * used to integrate with.</p>
+ * used to integrate with. For instance, using <code>{@link #RESTRICTED}.compose("com.my.app.*")</code>
+ * would extend the restricted set of permissions by allowing the com.my.app package.</p>
* @param src the new constraints
* @return the new permissions
*/
@@ -268,7 +271,7 @@ public interface JexlPermissions {
/**
* Checks that a package is valid for permission check.
- * @param pack the palcaga
+ * @param pack the package
* @return true if the class is not null, false otherwise
*/
default boolean validate(final Package pack) {
@@ -286,15 +289,15 @@ public interface JexlPermissions {
/**
* Checks that a constructor is valid for permission check.
- * @param ctor the constructor
+ * @param constructor the constructor
* @return true if constructor is not null and public, false otherwise
*/
- default boolean validate(final Constructor<?> ctor) {
- if (ctor == null) {
+ default boolean validate(final Constructor<?> constructor) {
+ if (constructor == null) {
return false;
}
// field must be public
- if (!Modifier.isPublic(ctor.getModifiers())) {
+ if (!Modifier.isPublic(constructor.getModifiers())) {
return false;
}
return true;
diff --git a/src/site/site.xml b/src/site/site.xml
index eec9a22f..d17a2f96 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -25,8 +25,8 @@
<body>
<menu name="JEXL">
<item name="Overview" href="index.html" />
- <item name="JEXL 3.3 Release notes" href="relnotes33.html"/>
- <item name="Javadoc 3.3" href="apidocs/index.html"/>
+ <item name="Release Notes" href="relnotes33.html"/>
+ <item name="Javadoc 3.3" href="apidocs/index.html"/>
<item name="Javadoc 2.1.1" href="javadocs/apidocs-2.1.1/index.html"/>
<item name="Javadoc 1.1" href="javadocs/apidocs-1.1/index.html"/>
<item name="Download" href="download_jexl.cgi"/>
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
index d2ff2ed0..68683c7f 100644
--- a/src/site/xdoc/index.xml
+++ b/src/site/xdoc/index.xml
@@ -119,91 +119,93 @@ and ensure their execution within controlled functional constraints.
</p>
<p>The following example illustrate these aspects. It uses a specific set of permissions to allow using
URI class and a tailored context to expose streams in a convenient manner.</p>
-
- <source><![CDATA[
-
-/**
+ <!--
+ using http://java2html.blogspot.com to prettify code, minor edits; ugly to look at a source, pretty rendered
+ -->
+ <div>
+<pre style="text-align: left; border: 1px dashed #008DEF; line-height: 18px; padding: 15px; font-size: 13px; font-family:'Courier New', Courier, monospace; overflow: auto;"><span style='color:#3F5FBF'>/**
* A test around scripting streams.
- */
-public class StreamTest {
- /** Our engine instance. */
- private final JexlEngine jexl;
+ */</span>
+<span style='font-weight:bold;color:#7B0052;'>public</span> <span style='font-weight:bold;color:#7B0052;'>class</span> StreamTest <span style='font-weight:bold;color:#D3171B'>{</span>
+ <span style='color:#3F5FBF'>/** Our engine instance. */</span>
+ <span style='font-weight:bold;color:#7B0052;'>private</span> <span style='font-weight:bold;color:#7B0052;'>final</span> JexlEngine jexl;
- public StreamTest() {
- // Restricting features; no loops, no side effects
- JexlFeatures features = new JexlFeatures()
- .loops(false)
- .sideEffectGlobal(false)
- .sideEffect(false);
- // Restricted permissions to a safe set but with URI allowed
- JexlPermissions permissions = new ClassPermissions(java.net.URI.class);
- // Create the engine
- jexl = new JexlBuilder().permissions(permissions).create();
- }
+ <span style='font-weight:bold;color:#7B0052;'>public</span> StreamTest() <span style='font-weight:bold;color:#D3171B'>{</span>
+ <span style='color:#3F7F5F'>// Restricting features; no loops, no side effects
+</span> JexlFeatures features = <span style='font-weight:bold;color:#7B0052;'>new</span> JexlFeatures()
+ .loops(<span style='font-weight:bold;color:#7B0052;'>false</span>)
+ .sideEffectGlobal(<span style='font-weight:bold;color:#7B0052;'>false</span>)
+ .sideEffect(<span style='font-weight:bold;color:#7B0052;'>false</span>);
+ <span style='color:#3F7F5F'>// Restricted permissions to a safe set but with URI allowed
+</span> JexlPermissions permissions = <span style='font-weight:bold;color:#7B0052;'>new</span> ClassPermissions(java.net.URI.class);
+ <span style='color:#3F7F5F'>// Create the engine
+</span> jexl = <span style='font-weight:bold;color:#7B0052;'>new</span> JexlBuilder().permissions(permissions).create();
+ <span style='font-weight:bold;color:#D3171B'>}</span>
- /**
+ <span style='color:#3F5FBF'>/**
* A MapContext that can operate on streams.
- */
- public static class StreamContext extends MapContext {
- /**
+ */</span>
+ <span style='font-weight:bold;color:#7B0052;'>public</span> <span style='font-weight:bold;color:#7B0052;'>static</span> <span style='font-weight:bold;color:#7B0052;'>class</span> StreamContext <span style='font-weight:bold;color:#7B0052;'>extends</span> MapContext <span style='font-weight:bold;color:#D3171B'>{</span>
+ <span style='color:#3F5FBF'>/**
* This allows using a JEXL lambda as a mapper.
* @param stream the stream
* @param mapper the lambda to use as mapper
* @return the mapped stream
- */
- public Stream<?> map(Stream<?> stream, final JexlScript mapper) {
- return stream.map( x -> mapper.execute(this, x));
- }
+ */</span>
+ <span style='font-weight:bold;color:#7B0052;'>public</span> Stream<?> map(Stream<?> stream, <span style='font-weight:bold;color:#7B0052;'>final</span> JexlScript mapper) <span style='font-weight:bold;color:#D3171B'>{</span>
+ <span style='font-weight:bold;color:#7B0052;'>return</span> stream.map( x -> mapper.execute(this, x));
+ <span style='font-weight:bold;color:#D3171B'>}</span>
- /**
+ <span style='color:#3F5FBF'>/**
* This allows using a JEXL lambda as a filter.
* @param stream the stream
* @param filter the lambda to use as filter
* @return the filtered stream
- */
- public Stream<?> filter(Stream<?> stream, final JexlScript filter) {
- return stream.filter(x -> x =! null && TRUE.equals(filter.execute(this, x)));
- }
- }
+ */</span>
+ <span style='font-weight:bold;color:#7B0052;'>public</span> Stream<?> filter(Stream<?> stream, <span style='font-weight:bold;color:#7B0052;'>final</span> JexlScript filter) <span style='font-weight:bold;color:#D3171B'>{</span>
+ <span style='font-weight:bold;color:#7B0052;'>return</span> stream.filter(x -> x =! <span style='font-weight:bold;color:#7B0052;'>null</span> "" TRUE.equals(filter.execute(this, x)));
+ <span style='font-weight:bold;color:#D3171B'>}</span>
+ <span style='font-weight:bold;color:#D3171B'>}</span>
@Test
- public void testURIStream() throws Exception {
- // let's assume a collection of uris need to be processed and transformed to be simplified ;
- // we want only http/https ones, only the host part and forcing an https scheme
- List<URI> uris = Arrays.asList(
- URI.create("http://user@www.apache.org:8000?qry=true"),
- URI.create("https://commons.apache.org/releases/prepare.html"),
- URI.create("mailto:henrib@apache.org")
+ <span style='font-weight:bold;color:#7B0052;'>public</span> <span style='font-weight:bold;color:#7B0052;'>void</span> testURIStream() <span style='font-weight:bold;color:#7B0052;'>throws</span> Exception <span style='font-weight:bold;color:#D3171B'>{</span>
+ <span style='color:#3F7F5F'>// let's assume a collection of uris need to be processed and transformed to be simplified ;
+</span> <span style='color:#3F7F5F'>// we want only http/https ones, only the host part and forcing an https scheme
+</span> List<URI> uris = Arrays.asList(
+ URI.create(<span style='color:#2A00FF'>"http://user@www.apache.org:8000?qry=true"</span>),
+ URI.create(<span style='color:#2A00FF'>"https://commons.apache.org/releases/prepare.html"</span>),
+ URI.create(<span style='color:#2A00FF'>"mailto:henrib@apache.org"</span>)
);
- // Create the test control, the expected result of our script evaluation
- List<?> control = uris.stream()
- .map(uri -> uri.getScheme().startsWith("http")? "https://" + uri.getHost() : null)
- .filter(x -> x != null)
+ <span style='color:#3F7F5F'>// Create the test control, the expected result of our script evaluation
+</span> List<?> control = uris.stream()
+ .map(uri -> uri.getScheme().startsWith(<span style='color:#2A00FF'>"http"</span>)? <span style='color:#2A00FF'>"https://"</span> + uri.getHost() : <span style='font-weight:bold;color:#7B0052;'>null</span>)
+ .filter(x -> x != <span style='font-weight:bold;color:#7B0052;'>null</span>)
.collect(Collectors.toList());
Assert.assertEquals(2, control.size());
- // Create scripts:
- // uri is the name of the variable used as parameter; the beans are exposed as properties
- // note the starts-with operator =^
- // note that uri is also used in the back-quoted string that performs variable interpolation
- JexlScript mapper = jexl.createScript("uri.scheme =^ 'http'? `https://${uri.host}` : null", "uri");
- // using the bang-bang / !! - JScript like - is the way to coerce to boolean in the filter
- JexlScript transform = jexl.createScript(
- "list.stream().map(mapper).filter(x -> !!x).collect(Collectors.toList())", "list");
+ <span style='color:#3F7F5F'>// Create scripts:
+</span> <span style='color:#3F7F5F'>// uri is the name of the variable used as parameter; the beans are exposed as properties
+</span> <span style='color:#3F7F5F'>// note the starts-with operator =^
+</span> <span style='color:#3F7F5F'>// note that uri is also used in the back-quoted string that performs variable interpolation
+</span> JexlScript mapper = jexl.createScript(<span style='color:#2A00FF'>"uri.scheme =^ 'http'? `https://${uri.host}` : null"</span>, <span style='color:#2A00FF'>"uri"</span>);
+ <span style='color:#3F7F5F'>// using the bang-bang / !! - JScript like - is the way to coerce to boolean in the filter
+</span> JexlScript transform = jexl.createScript(
+ <span style='color:#2A00FF'>"list.stream().map(mapper).filter(x -> !!x).collect(Collectors.toList())"</span>, <span style='color:#2A00FF'>"list"</span>);
- // Execute scripts:
- JexlContext sctxt = new StreamContext();
- // expose the static methods of Collectors; java.util.* is allowed by permissions
- sctxt.set("Collectors", Collectors.class);
- // expose the mapper script as a global variable in the context
- sctxt.set("mapper", mapper);
+ <span style='color:#3F7F5F'>// Execute scripts:
+</span> JexlContext sctxt = <span style='font-weight:bold;color:#7B0052;'>new</span> StreamContext();
+ <span style='color:#3F7F5F'>// expose the static methods of Collectors; java.util.* is allowed by permissions
+</span> sctxt.set(<span style='color:#2A00FF'>"Collectors"</span>, Collectors.class);
+ <span style='color:#3F7F5F'>// expose the mapper script as a global variable in the context
+</span> sctxt.set(<span style='color:#2A00FF'>"mapper"</span>, mapper);
Object transformed = transform.execute(sctxt, uris);
- Assert.assertTrue(transformed instanceof List<?>);
+ Assert.assertTrue(transformed <span style='font-weight:bold;color:#7B0052;'>instanceof</span> List<?>);
Assert.assertEquals(control, transformed);
- }
-}
- ]]></source>
+ <span style='font-weight:bold;color:#D3171B'>}</span>
+<span style='font-weight:bold;color:#D3171B'>}</span></pre>
+ </div>
+
</section>
<section name="Extensions to JSTL Expression Language">
diff --git a/src/site/xdoc/relnotes33.xml b/src/site/xdoc/relnotes33.xml
index 982cfa89..344d6bbd 100644
--- a/src/site/xdoc/relnotes33.xml
+++ b/src/site/xdoc/relnotes33.xml
@@ -38,9 +38,8 @@
(see <a href="apidocs/org/apache/commons/jexl3/introspection/JexlPermissions.html">JexlPermissions</a>,
<a href="apidocs/org/apache/commons/jexl3/JexlBuilder.html">JexlBuilder</a> and
<a href="apidocs/org/apache/commons/jexl3/scripting/JexlScriptEngine.html">JexlScriptEngine</a> ) or use this
- opportunity to reduce exposure. Whether Files, URLs, networking, processes, class-loaders or reflection features are
- accessible are part of the choice to make.</p><p>
- <strong>Any CVE linked to JEXL should try resolution by first upgrading to JEXL 3.3.</strong>
+ opportunity to reduce exposure. Whether Files, URLs, networking, processes, class-loaders or reflection classes
+ or whether loops or side-effects are accessible are part of your choice to make.
</p>
</section>
<section name="What's new in 3.3:">
@@ -50,7 +49,7 @@
a security manager that controls what JEXL can introspect and thus expose to scripts.
</p><p>
Used in conjunction with options (JexlOptions) and features (JexlFeatures), the permissions (JexlPermissions)
- allow fine-tuning the scripting integration into any project.
+ allow fine-tuning the end-user freedom and scripting integration through syntactic and semantic sanitation.
</p><p>
JEXL 3.3 also adds some syntactic (ECMAScript) features (let, const, =>, for, ...) to further reduce
the skill set required to write scripts.