From 6c3f0c36ff6084962460b1703e197572f1640984 Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: Thu, 6 Jan 2022 14:31:09 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E7=9B=AE?=
 =?UTF-8?q?=E6=A0=87=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=AA=8C=E8=AF=81=E5=8C=85?=
 =?UTF-8?q?=E5=90=8D=E7=99=BD=E5=90=8D=E5=8D=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/ruoyi/common/constant/Constants.java  | 12 +++++++++-
 .../quartz/controller/SysJobController.java   | 17 ++++++++++----
 .../com/ruoyi/quartz/util/ScheduleUtils.java  | 22 +++++++++++++++++++
 3 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
index e94cef40..2ed72610 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -117,9 +117,19 @@ public class Constants
      */
     public static final String LOOKUP_LDAP = "ldap:";
 
+    /**
+     * LDAPS 远程方法调用
+     */
+    public static final String LOOKUP_LDAPS = "ldaps:";
+
+    /**
+     * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
+     */
+    public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
+
     /**
      * 定时任务违规的字符
      */
     public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
-            "org.springframework" };
+            "org.springframework", "org.apache" };
 }
\ No newline at end of file
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
index 0d12de0a..2b8a79d2 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
@@ -25,6 +25,7 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.quartz.domain.SysJob;
 import com.ruoyi.quartz.service.ISysJobService;
 import com.ruoyi.quartz.util.CronUtils;
+import com.ruoyi.quartz.util.ScheduleUtils;
 
 /**
  * 调度任务信息操作处理
@@ -140,18 +141,22 @@ public class SysJobController extends BaseController
         {
             return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用");
         }
-        else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP))
+        else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS }))
         {
             return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap'调用");
         }
         else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS }))
         {
-            return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用");
+            return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用");
         }
         else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR))
         {
             return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规");
         }
+        else if (!ScheduleUtils.whiteList(job.getInvokeTarget()))
+        {
+            return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内");
+        }
         job.setCreateBy(getLoginName());
         return toAjax(jobService.insertJob(job));
     }
@@ -184,18 +189,22 @@ public class SysJobController extends BaseController
         {
             return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用");
         }
-        else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP))
+        else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS }))
         {
             return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap'调用");
         }
         else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS }))
         {
-            return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用");
+            return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用");
         }
         else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR))
         {
             return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规");
         }
+        else if (!ScheduleUtils.whiteList(job.getInvokeTarget()))
+        {
+            return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内");
+        }
         return toAjax(jobService.updateJob(job));
     }
 
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java
index b7c2f536..2ca398a9 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java
@@ -10,9 +10,11 @@ import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.TriggerBuilder;
 import org.quartz.TriggerKey;
+import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.ScheduleConstants;
 import com.ruoyi.common.exception.job.TaskException;
 import com.ruoyi.common.exception.job.TaskException.Code;
+import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.quartz.domain.SysJob;
 
 /**
@@ -110,4 +112,24 @@ public class ScheduleUtils
                         + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR);
         }
     }
+
+    /**
+     * 检查包名是否为白名单配置
+     * 
+     * @param invokeTarget 目标字符串
+     * @return 结果
+     */
+    public static boolean whiteList(String invokeTarget)
+    {
+        String packageName = StringUtils.substringBefore(invokeTarget, ")");
+        int count = StringUtils.countMatches(packageName, ".");
+        if (count > 1)
+        {
+            if (!StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
 }
\ No newline at end of file