diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java index b77dea8..c642a0e 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java @@ -8,6 +8,7 @@ package com.keyware.sonar.java.rules; import com.keyware.sonar.java.rules.checkers.ABCVarNameChecker; import com.keyware.sonar.java.rules.checkers.AbsolutePathDetectorChecker; +import com.keyware.sonar.java.rules.checkers.DynamicCodeChecker; import com.keyware.sonar.java.rules.checkers.PathAndKeywordCheck; import org.sonar.plugins.java.api.JavaCheck; @@ -35,7 +36,8 @@ public final class RulesList { return Collections.unmodifiableList(Arrays.asList( ABCVarNameChecker.class, AbsolutePathDetectorChecker.class, - PathAndKeywordCheck.class + PathAndKeywordCheck.class, + DynamicCodeChecker.class /*SpringControllerRequestMappingEntityRule.class, AvoidAnnotationRule.class, AvoidBrandInMethodNamesRule.class, diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/DynamicCodeChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/DynamicCodeChecker.java new file mode 100644 index 0000000..11b14c4 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/DynamicCodeChecker.java @@ -0,0 +1,58 @@ +package com.keyware.sonar.java.rules.checkers; + + +import org.sonar.check.Rule; +import org.sonar.java.ast.visitors.SubscriptionVisitor; +import org.sonar.plugins.java.api.tree.*; +import org.springframework.expression.EvaluationException; + +import java.lang.reflect.Method; +import java.sql.ClientInfoStatus; +import java.util.Collections; +import java.util.List; + + +@Rule(key = "SessionExpirationDateChecker") + +//检测代码中包含动态代码执行操作时,工具进行提示 +public class DynamicCodeChecker extends SubscriptionVisitor { + + @Override + public List nodesToVisit() { + /** + * Tree.Kind.METHOD:方法节点 + * Tree.Kind.BLOCK:方法的代码块节点 + * Tree.Kind.METHOD_INVOCATION: 方法的调用节点 + */ + return Collections.singletonList( + Tree.Kind.METHOD_INVOCATION + ); + } + + @Override + public void visitNode(Tree tree) { + MethodInvocationTree node = (MethodInvocationTree) tree; + System.out.println(node); + var expressionTree = node.methodSelect(); + if (expressionTree instanceof MemberSelectExpressionTree) { + var exprTree = (MemberSelectExpressionTree) expressionTree; + var name = exprTree.identifier(); + if ("eval".equals(name.toString())) { + var varNameNode = exprTree.expression(); + if (varNameNode instanceof IdentifierTree) { + var varName = (IdentifierTree) varNameNode; + var symbol = varName.symbol(); + var varDecler = symbol.declaration(); + if (varDecler != null) { + var variableTree = (VariableTree) varDecler; + var typeName = variableTree.type().toString(); + if ("ScriptEngine".equals(typeName)) { + context.reportIssue(this, tree, "程序设计时禁止动态构建代码进行功能实现"); + } + } + } + } + } + } + +} diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/DynamicCodeChecker.html b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/DynamicCodeChecker.html new file mode 100644 index 0000000..0b9a531 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/DynamicCodeChecker.html @@ -0,0 +1,9 @@ +

程序设计时禁止动态构建代码进行功能实现

+

程序设计时禁止动态构建代码进行功能实现,如必须动态构建,应在动态构建代码语句前对输入数据进行验证,确保仅能用于构建允许执行的代码

+
+
+
+

合规解决方案

+
+
+
diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/DynamicCodeChecker.json b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/DynamicCodeChecker.json new file mode 100644 index 0000000..95366f0 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/DynamicCodeChecker.json @@ -0,0 +1,13 @@ +{ + "title": "程序设计时禁止动态构建代码进行功能实现", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "28suo" + ], + "defaultSeverity": "Minor" +} \ No newline at end of file diff --git a/sonar-keyware-plugins-java/src/test/files/DynamicCodeCheckerRule.java b/sonar-keyware-plugins-java/src/test/files/DynamicCodeCheckerRule.java new file mode 100644 index 0000000..c14de8f --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/files/DynamicCodeCheckerRule.java @@ -0,0 +1,22 @@ +class DynamicCode { + public void dyan() { + String regular = "function regular(args1,args2,args3){................}"; + ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript"); + try { + engine.eval(regular); // Noncompliant {{程序设计时禁止动态构建代码进行功能实现}} + if (engine instanceof Invocable) { + Invocable invoke = (Invocable) engine; + String result = (String) invoke.invokeFunction( + "regular", + args1, + args2, + args3); + System.out.println(result); + } else { + System.out.println("error"); + } + } catch (ScriptException e) { + System.out.println("表达式runtime错误:" + e.getMessage()); + } + } +} diff --git a/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/DynamicCodeCheckerTest.java b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/DynamicCodeCheckerTest.java new file mode 100644 index 0000000..e4fdef7 --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/DynamicCodeCheckerTest.java @@ -0,0 +1,29 @@ +package com.keyware.sonar.java.rules.checkers; + + +import com.keyware.sonar.java.utils.FilesUtils; +import org.junit.jupiter.api.Test; +import org.sonar.java.checks.verifier.CheckVerifier; + +public class DynamicCodeCheckerTest { + + @Test + void detected() { + + + DynamicCodeChecker rule = new DynamicCodeChecker(); + + + // Verifies that the check will raise the adequate issues with the expected message. + // In the test file, lines which should raise an issue have been commented out + // by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}" + CheckVerifier.newVerifier() + .onFile("src/test/files/DynamicCodeCheckerRule.java") + .withCheck(rule) + .withClassPath(FilesUtils.getClassPath("target/test-jars")) + .verifyIssues(); + + + } + +}