You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2020/04/04 07:26:24 UTC

[syncope] branch 2_0_X updated: Sandboxing JEXL (#171)

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch 2_0_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/2_0_X by this push:
     new e07263d  Sandboxing JEXL (#171)
e07263d is described below

commit e07263dedad7ed44e188abb11260fa3061afadc4
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Sat Apr 4 08:28:38 2020 +0200

    Sandboxing JEXL (#171)
---
 .../provisioning/java/jexl/ClassFreeUberspect.java |  41 --------
 .../provisioning/java/jexl/EmptyClassLoader.java   |   1 -
 .../core/provisioning/java/jexl/JexlUtils.java     |   2 +-
 .../provisioning/java/jexl/SandboxUberspect.java   | 105 +++++++++++++++++++++
 .../notification/DefaultNotificationManager.java   |   2 +-
 5 files changed, 107 insertions(+), 44 deletions(-)

diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java
deleted file mode 100644
index aec38b8..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/ClassFreeUberspect.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java.jexl;
-
-import org.apache.commons.jexl3.internal.introspection.Uberspect;
-import org.apache.commons.jexl3.introspection.JexlMethod;
-import org.apache.commons.jexl3.introspection.JexlPropertyGet;
-
-class ClassFreeUberspect extends Uberspect {
-
-    ClassFreeUberspect() {
-        super(null, null);
-    }
-
-    @Override
-    public JexlPropertyGet getPropertyGet(final Object obj, final Object identifier) {
-        return "class".equals(identifier) ? null : super.getPropertyGet(obj, identifier);
-    }
-
-    @Override
-    public JexlMethod getMethod(final Object obj, final String method, final Object... args) {
-        return "getClass".equals(method) ? null : super.getMethod(obj, method, args);
-    }
-
-}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java
index 037113e..120c33b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/EmptyClassLoader.java
@@ -32,5 +32,4 @@ class EmptyClassLoader extends ClassLoader {
     protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
         throw new ClassNotFoundException("This classloader won't attemp to load " + name);
     }
-
 }
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
index d02042a..4c0e873 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
@@ -71,7 +71,7 @@ public final class JexlUtils {
         synchronized (LOG) {
             if (JEXL_ENGINE == null) {
                 JEXL_ENGINE = new JexlBuilder().
-                        uberspect(new ClassFreeUberspect()).
+                        uberspect(new SandboxUberspect()).
                         loader(new EmptyClassLoader()).
                         namespaces(Collections.<String, Object>singletonMap("syncope", new SyncopeJexlFunctions())).
                         cache(512).
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/SandboxUberspect.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/SandboxUberspect.java
new file mode 100644
index 0000000..0e4dd2e
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/SandboxUberspect.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.jexl;
+
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.commons.jexl3.JexlEngine;
+import org.apache.commons.jexl3.internal.introspection.Uberspect;
+import org.apache.commons.jexl3.introspection.JexlMethod;
+import org.apache.commons.jexl3.introspection.JexlPropertySet;
+import org.apache.commons.jexl3.introspection.JexlUberspect;
+import org.apache.commons.logging.LogFactory;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.Membership;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+
+class SandboxUberspect extends Uberspect {
+
+    private static final Set<String> COLLECTION_METHODS = Collections.unmodifiableSet(new HashSet<>(
+            Arrays.asList("contains", "containsAll", "isEmpty", "size", "iterator", "toString")));
+
+    private static final Set<String> LIST_METHODS = Collections.unmodifiableSet(new HashSet<>(
+            Arrays.asList("get", "indexOf", "lastIndexOf", "toString")));
+
+    private static final Set<String> MAP_METHODS = Collections.unmodifiableSet(new HashSet<>(
+            Arrays.asList("get", "getOrDefault", "containsKey", "containsValue", "toString")));
+
+    SandboxUberspect() {
+        super(LogFactory.getLog(JexlEngine.class), JexlUberspect.JEXL_STRATEGY);
+    }
+
+    @Override
+    public JexlMethod getConstructor(final Object ctorHandle, final Object... args) {
+        return null;
+    }
+
+    @Override
+    public JexlMethod getMethod(final Object obj, final String method, final Object... args) {
+        if (obj instanceof AnyTO || obj instanceof Any
+                || obj instanceof PlainAttr || obj instanceof AttrTO
+                || obj instanceof MembershipTO || obj instanceof Membership
+                || obj instanceof Realm || obj instanceof RealmTO) {
+
+            return super.getMethod(obj, method, args);
+        } else if (obj instanceof SyncopeJexlFunctions) {
+            return super.getMethod(obj, method, args);
+        } else if (obj instanceof Optional) {
+            return super.getMethod(obj, method, args);
+        } else if (obj.getClass().isArray()) {
+            return super.getMethod(obj, method, args);
+        } else if (obj instanceof String) {
+            return super.getMethod(obj, method, args);
+        } else if (obj instanceof Date || obj instanceof Instant) {
+            return super.getMethod(obj, method, args);
+        } else if (obj instanceof Map && MAP_METHODS.contains(method)) {
+            return super.getMethod(obj, method, args);
+        } else if (obj instanceof List && (LIST_METHODS.contains(method) || COLLECTION_METHODS.contains(method))) {
+            return super.getMethod(obj, method, args);
+        } else if (obj instanceof Collection && COLLECTION_METHODS.contains(method)) {
+            return super.getMethod(obj, method, args);
+        }
+        return null;
+    }
+
+    @Override
+    public JexlPropertySet getPropertySet(final Object obj, final Object identifier, final Object arg) {
+        return null;
+    }
+
+    @Override
+    public JexlPropertySet getPropertySet(
+            final List<PropertyResolver> resolvers, final Object obj, final Object identifier, final Object arg) {
+
+        return null;
+    }
+}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java
index a00e070..0907b7a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java
@@ -376,7 +376,7 @@ public class DefaultNotificationManager implements NotificationManager {
                     } else if (any instanceof Group) {
                         model.put("group", groupDataBinder.getGroupTO((Group) any, true));
                     } else if (any instanceof AnyObject) {
-                        model.put("group", anyObjectDataBinder.getAnyObjectTO((AnyObject) any, true));
+                        model.put("anyObject", anyObjectDataBinder.getAnyObjectTO((AnyObject) any, true));
                     }
 
                     NotificationTask notificationTask = getNotificationTask(notification, any, model);