From f650fbb2098a06476a2db5e6a947733c8fafca8c Mon Sep 17 00:00:00 2001 From: RenFengJiang <1111> Date: Sat, 13 Jan 2024 13:34:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=87=86=E5=88=99=EF=BC=9A?= =?UTF-8?q?=E5=BA=94=E4=BD=BF=E7=94=A8=E5=8D=95=E5=90=91=E4=B8=8D=E5=8F=AF?= =?UTF-8?q?=E9=80=86=E7=9A=84=E5=8A=A0=E5=AF=86=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../checkers/Md5PassWordVerifyChecker.java | 93 +++++++++++++++++++ .../rules/java/Md5PassWordVerifyChecker.htm | 9 ++ .../rules/java/Md5PassWordVerifyChecker.json | 13 +++ .../src/test/files/Md5PassWordVerifyRule.java | 10 ++ .../Md5PassWordVerifyCheckerTest.java | 31 +++++++ 5 files changed, 156 insertions(+) create mode 100644 sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyChecker.java create mode 100644 sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Md5PassWordVerifyChecker.htm create mode 100644 sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Md5PassWordVerifyChecker.json create mode 100644 sonar-keyware-plugins-java/src/test/files/Md5PassWordVerifyRule.java create mode 100644 sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyCheckerTest.java diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyChecker.java new file mode 100644 index 0000000..38ae306 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyChecker.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:Java 信息安全性设计准则 + * 项目描述:用于检查Java源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ +package com.keyware.sonar.java.rules.checkers; + +import org.sonar.check.Rule; +import org.sonar.java.ast.parser.ArgumentListTreeImpl; +import org.sonar.java.model.declaration.VariableTreeImpl; +import org.sonar.java.model.expression.IdentifierTreeImpl; +import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl; +import org.sonar.java.model.expression.MethodInvocationTreeImpl; +import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; +import org.sonar.plugins.java.api.tree.*; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +/** + * TODO Md5PassWordVerifyChecker + * + * @author RenFengJiang + * @date 2024/1/13 + */ +@Rule(key = "Md5PassWordVerifyChecker") +public class Md5PassWordVerifyChecker extends IssuableSubscriptionVisitor { + @Override + public List nodesToVisit() { + /** + * Tree.Kind.METHOD:方法节点 + * Tree.Kind.BLOCK:方法的代码块节点 + * Tree.Kind.METHOD_INVOCATION: 方法的调用节点 + */ + return Collections.singletonList(Tree.Kind.METHOD); + } + + @Override + public void visitNode(Tree tree) { + MethodTree node = (MethodTree) tree; + var bodyVisitor = new MethodeBodyVisitor(this); + node.block().accept(bodyVisitor); + } + + + static class MethodeBodyVisitor extends BaseTreeVisitor { + //存放盐值后的密码 + public String strPassWord = ""; + private final Md5PassWordVerifyChecker checker; + + MethodeBodyVisitor(Md5PassWordVerifyChecker checker) { + this.checker = checker; + } + + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + //获取到方法调用 + ExpressionTree expressionTree = tree.methodSelect(); + if (expressionTree instanceof MemberSelectExpressionTreeImpl) { + //获取到调用的方法 + MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; + if ("setPassWord".equals(memberSelectExpressionTree.identifier().name())) { + Tree parent = tree.arguments(); + if (parent instanceof ArgumentListTreeImpl) { + for (ExpressionTree expressionTree1 : (ArgumentListTreeImpl) parent) { + if (expressionTree1 instanceof IdentifierTreeImpl) { + IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree1; + //判断set中使用的参数 + if(!identifierTree.name().equals(strPassWord)){ + checker.context.reportIssue(checker, identifierTree, "应使用单向不可逆的加密算法"); + } + } + } + } + //判断是否使用单向不可逆加密方式 + }else if(memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("md5hex") || memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("encrypt")){ + Tree parent = memberSelectExpressionTree.parent(); + if(parent instanceof MethodInvocationTreeImpl){ + MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) parent; + Tree parent1 = methodInvocationTree.parent(); + if(parent1 instanceof VariableTreeImpl){ + VariableTreeImpl variableTree = (VariableTreeImpl) parent1; + //获取加密后的名称 + strPassWord = variableTree.simpleName().name(); + } + } + } + } + } + } +} diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Md5PassWordVerifyChecker.htm b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Md5PassWordVerifyChecker.htm new file mode 100644 index 0000000..7d76cba --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Md5PassWordVerifyChecker.htm @@ -0,0 +1,9 @@ +

应使用单向不可逆的加密算法

+

使用单向不可逆的加密算法对口令进行加密并存储在外部文件或数据库中

+
+
+
+

合规解决方案

+
+
+
diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Md5PassWordVerifyChecker.json b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Md5PassWordVerifyChecker.json new file mode 100644 index 0000000..4c148e2 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Md5PassWordVerifyChecker.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/Md5PassWordVerifyRule.java b/sonar-keyware-plugins-java/src/test/files/Md5PassWordVerifyRule.java new file mode 100644 index 0000000..c500bc3 --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/files/Md5PassWordVerifyRule.java @@ -0,0 +1,10 @@ +class Md5PassWordVerifyRule{ + public static void cs(Student studnet){ + // 结合盐值和口令进行散列计算 +// String password = DigestUtils.md5Hex(str); + + studnet.setPassWord(password);// Noncompliant {{应使用单向不可逆的加密算法}} + + } + +} \ No newline at end of file diff --git a/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyCheckerTest.java b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyCheckerTest.java new file mode 100644 index 0000000..2ae6355 --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyCheckerTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:Java 信息安全性设计准则 + * 项目描述:用于检查Java源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ +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; + +/** + * TODO Md5PassWordVerifyCheckerTest + * + * @author RenFengJiang + * @date 2024/1/13 + */ +public class Md5PassWordVerifyCheckerTest { + @Test + void detected() { + Md5PassWordVerifyChecker rule = new Md5PassWordVerifyChecker(); + + + CheckVerifier.newVerifier() + .onFile("src/test/files/Md5PassWordVerifyRule.java") + .withCheck(rule) + .withClassPath(FilesUtils.getClassPath("target/test-jars")) + .verifyIssues(); + } +}