diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/AuthenticationChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/AuthenticationChecker.java index 87bce29..3bf82bb 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/AuthenticationChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/AuthenticationChecker.java @@ -8,7 +8,6 @@ package com.keyware.sonar.java.rules.checkers; import org.sonar.check.Rule; -import org.sonar.java.model.DefaultModuleScannerContext; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.ModuleScannerContext; import org.sonar.plugins.java.api.internal.EndOfAnalysis; @@ -99,10 +98,9 @@ public class AuthenticationChecker extends IssuableSubscriptionVisitor implement @Override public void endOfAnalysis(ModuleScannerContext context) { - var defaultContext = (DefaultModuleScannerContext) context; if (!isValidPathFound) { System.out.println("应通过用户名口令、数据证书等其他手段对用户身份进行验证"); - defaultContext.addIssueOnProject(this, "应通过用户名口令、数据证书等其他手段对用户身份进行验证"); + context.addIssueOnProject(this, "应通过用户名口令、数据证书等其他手段对用户身份进行验证"); } } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/CookieSensitiveParameterCheck.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/CookieSensitiveParameterCheck.java index 61614bd..a26cc40 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/CookieSensitiveParameterCheck.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/CookieSensitiveParameterCheck.java @@ -30,7 +30,7 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor { @Override public List nodesToVisit() { - return Arrays.asList(Tree.Kind.METHOD_INVOCATION, Tree.Kind.VARIABLE, Tree.Kind.STRING_LITERAL); + return Arrays.asList(Tree.Kind.METHOD_INVOCATION, Tree.Kind.VARIABLE); } @Override @@ -39,8 +39,6 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor { visitMethodInvocation((MethodInvocationTree) tree); } else if (tree.is(Tree.Kind.VARIABLE)) { visitVariable((VariableTree) tree); - } else if (tree.is(Tree.Kind.STRING_LITERAL)) { - visitStringLiteral((LiteralTree) tree); } } @@ -94,14 +92,12 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor { System.out.println("Cookie参数设置中的value属性与局部变量一致: " + variableName); reportIssue(expression, "Cookie参数设置中包含敏感字段"); } - } - } - - private void visitStringLiteral(LiteralTree literalTree) { - String literalValue = literalTree.value(); - if (containsSensitiveParam(literalValue)) { - System.out.println("Cookie参数设置中包含敏感字段: " + literalValue); - reportIssue(literalTree, "Cookie参数设置中包含敏感字段"); + } else if (expression.is(Tree.Kind.STRING_LITERAL)) { + String literalValue = LiteralTree.class.cast(expression).value(); + if (containsSensitiveParam(literalValue)) { + System.out.println("Cookie参数设置中的name属性包含敏感字符串: " + literalValue); + reportIssue(expression, "Cookie参数设置中包含敏感字段"); + } } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java index 201d110..86212e3 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java @@ -10,7 +10,6 @@ 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.*; @@ -56,28 +55,26 @@ public class HashSaltPassWordChecker extends IssuableSubscriptionVisitor { @Override public void visitMethodInvocation(MethodInvocationTree tree) { -// 获取到方法调用 + //获取到方法调用 ExpressionTree expressionTree = tree.methodSelect(); - if (expressionTree instanceof MemberSelectExpressionTreeImpl) { -// 获取到调用的方法 - MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; + if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) { + // 获取到调用的方法 + MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) 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 { - checker.context.reportIssue(checker, expressionTree1, "应使用盐值计算口令"); + Arguments arguments = tree.arguments(); + for (ExpressionTree expressionTree1 : arguments) { + if (expressionTree1.is(Tree.Kind.IDENTIFIER)) { + IdentifierTree identifierTree = (IdentifierTree) expressionTree1; + // 判断set中使用的参数 + if(!identifierTree.name().equals(strPassWord)){ + checker.context.reportIssue(checker, identifierTree, "应使用盐值计算口令"); } + } else { + System.out.println(expressionTree1); + checker.context.reportIssue(checker, expressionTree1, "应使用盐值计算口令"); } } -// 判断是否是生成的加盐后的密码 - }else if("BCrypt".equals(memberSelectExpressionTree.expression().toString()) && "hashpw".equals(memberSelectExpressionTree.identifier().name())){ + } else if("BCrypt".equals(memberSelectExpressionTree.expression().toString()) && "hashpw".equals(memberSelectExpressionTree.identifier().name())){ Tree parent = memberSelectExpressionTree.parent(); if(parent instanceof MethodInvocationTreeImpl){ MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) parent; diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HttpInputDataChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HttpInputDataChecker.java index 16b2a1b..574d7c9 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HttpInputDataChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HttpInputDataChecker.java @@ -7,15 +7,11 @@ package com.keyware.sonar.java.rules.checkers; import org.sonar.check.Rule; -import org.sonar.java.ast.parser.ArgumentListTreeImpl; -import org.sonar.java.model.expression.BinaryExpressionTreeImpl; -import org.sonar.java.model.expression.IdentifierTreeImpl; -import org.sonar.java.model.expression.LiteralTreeImpl; -import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -54,12 +50,12 @@ public class HttpInputDataChecker extends IssuableSubscriptionVisitor { @Override public void visitIfStatement(IfStatementTree tree) { ExpressionTree condition = tree.condition(); - if (condition instanceof BinaryExpressionTreeImpl) { - BinaryExpressionTreeImpl binaryExpressionTree = (BinaryExpressionTreeImpl) condition; - List children = binaryExpressionTree.children(); - for (Tree child:children) { - if(child instanceof IdentifierTreeImpl){ - IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) child; + if (condition.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO)) { + BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) condition; + + for (Tree operand : Arrays.asList(binaryExpressionTree.leftOperand(), binaryExpressionTree.rightOperand())) { + if (operand.is(Tree.Kind.IDENTIFIER)) { + IdentifierTree identifierTree = (IdentifierTree) operand; list.add(identifierTree.name()); } } @@ -69,24 +65,20 @@ public class HttpInputDataChecker extends IssuableSubscriptionVisitor { @Override public void visitMethodInvocation(MethodInvocationTree tree) { ExpressionTree expressionTree = tree.methodSelect(); - if(expressionTree instanceof MemberSelectExpressionTreeImpl){ - MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; - if("setHeader".equals(memberSelectExpressionTree.identifier().name()) || "addHeader".equals(memberSelectExpressionTree.identifier().name())){ + if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) { + MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree; + if ("setHeader".equals(memberSelectExpressionTree.identifier().name()) + || "addHeader".equals(memberSelectExpressionTree.identifier().name())) { Arguments arguments = tree.arguments(); - if(arguments instanceof ArgumentListTreeImpl){ - for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { - if(argument instanceof LiteralTreeImpl){ - LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; - if("STRING_LITERAL".equals(literalTree.kind().name())){ - checker.context.reportIssue(checker, literalTree, "HTTP输入数据验证"); - break; - } - }else if(argument instanceof IdentifierTreeImpl){ - IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) argument; - if(!list.contains(identifierTree.name())){ - checker.context.reportIssue(checker, identifierTree, "HTTP输入数据验证"); - break; - } + for (ExpressionTree argument : arguments) { + if(argument.is(Tree.Kind.STRING_LITERAL)){ + checker.context.reportIssue(checker, argument, "HTTP输入数据验证"); + break; + } else if(argument.is(Tree.Kind.IDENTIFIER)){ + IdentifierTree identifierTree = (IdentifierTree) argument; + if(!list.contains(identifierTree.name())){ + checker.context.reportIssue(checker, identifierTree, "HTTP输入数据验证"); + break; } } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/InputSQLVerifyChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/InputSQLVerifyChecker.java index b47c471..0861c89 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/InputSQLVerifyChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/InputSQLVerifyChecker.java @@ -7,9 +7,6 @@ package com.keyware.sonar.java.rules.checkers; import org.sonar.check.Rule; -import org.sonar.java.ast.parser.ArgumentListTreeImpl; -import org.sonar.java.model.expression.IdentifierTreeImpl; -import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.*; @@ -64,19 +61,17 @@ public class InputSQLVerifyChecker extends IssuableSubscriptionVisitor { @Override public void visitMethodInvocation(MethodInvocationTree tree) { ExpressionTree expressionTree = tree.methodSelect(); - if(expressionTree instanceof MemberSelectExpressionTreeImpl){ - MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; - if("prepareStatement".equals(memberSelectExpressionTree.identifier().name())){ + if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) { + MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree; + if ("prepareStatement".equals(memberSelectExpressionTree.identifier().name())) { Arguments arguments = tree.arguments(); - if(arguments instanceof ArgumentListTreeImpl){ - for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { - if (argument instanceof IdentifierTreeImpl){ - IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) argument; - String name = identifierTree.name(); - //判断使用的sql是否存在集合中 - if(!lists.contains(name)){ - checker.context.reportIssue(checker,argument,"使用sql语句前应对其进行验证"); - } + for (ExpressionTree argument : arguments) { + if (argument.is(Tree.Kind.IDENTIFIER)) { + IdentifierTree identifierTree = (IdentifierTree) argument; + String name = identifierTree.name(); + // 判断使用的sql是否存在集合中 + if (!lists.contains(name)) { + checker.context.reportIssue(checker, argument, "使用sql语句前应对其进行验证"); } } } 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 index c9a19b4..fd67e8c 100644 --- 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 @@ -7,11 +7,6 @@ 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.*; @@ -58,33 +53,34 @@ public class Md5PassWordVerifyChecker extends IssuableSubscriptionVisitor { public void visitMethodInvocation(MethodInvocationTree tree) { //获取到方法调用 ExpressionTree expressionTree = tree.methodSelect(); - if (expressionTree instanceof MemberSelectExpressionTreeImpl) { - //获取到调用的方法 - MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; + if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) { + MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) 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 { - checker.context.reportIssue(checker, expressionTree1, "应使用单向不可逆的加密算法"); + Arguments arguments = tree.arguments(); + //改用arguments,这里没必要再用 instanceof 检查接口了 + for (ExpressionTree argument : arguments) { + if (argument.is(Tree.Kind.IDENTIFIER)) { + IdentifierTree identifierTree = (IdentifierTree) argument; + String name = identifierTree.name(); + if (!name.equals(strPassWord)) { + System.out.println(identifierTree); + checker.context.reportIssue(checker, identifierTree, "应使用单向不可逆的加密算法"); } + } else { + System.out.println(argument); + checker.context.reportIssue(checker, argument, "应使用单向不可逆的加密算法"); } } - //判断是否使用单向不可逆加密方式 - }else if(memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("md5hex") || memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("encrypt")){ + } 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; + //对parent进行了instanceof检查,这是不正确的,应该使用is(Tree.Kind.SOMETHING) + if (parent.is(Tree.Kind.METHOD_INVOCATION)) { + MethodInvocationTree methodInvocationTree = (MethodInvocationTree) parent; Tree parent1 = methodInvocationTree.parent(); - if(parent1 instanceof VariableTreeImpl){ - VariableTreeImpl variableTree = (VariableTreeImpl) parent1; - //获取加密后的名称 + //这同样是对parent1进行了instanceof检查,这是不正确的,应该使用is(Tree.Kind.SOMETHING) + if (parent1.is(Tree.Kind.VARIABLE)) { + VariableTree variableTree = (VariableTree) parent1; strPassWord = variableTree.simpleName().name(); } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java index dc854c1..a5226df 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java @@ -8,17 +8,10 @@ package com.keyware.sonar.java.rules.checkers; import org.sonar.check.Rule; -import org.sonar.java.ast.parser.ArgumentListTreeImpl; -import org.sonar.java.model.DefaultModuleScannerContext; -import org.sonar.java.model.expression.LiteralTreeImpl; -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.ModuleScannerContext; import org.sonar.plugins.java.api.internal.EndOfAnalysis; -import org.sonar.plugins.java.api.tree.Arguments; -import org.sonar.plugins.java.api.tree.ExpressionTree; -import org.sonar.plugins.java.api.tree.Tree; +import org.sonar.plugins.java.api.tree.*; import java.util.Collections; import java.util.List; @@ -35,45 +28,35 @@ import java.util.List; public class OptionsVerifyChecker extends IssuableSubscriptionVisitor implements EndOfAnalysis { private boolean boo = true; + @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) { - //判断项目是否配置 - if(boo){ - MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) tree; + if(boo) { + MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; ExpressionTree expressionTree = methodInvocationTree.methodSelect(); - if(expressionTree instanceof MemberSelectExpressionTreeImpl){ - MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; - //获取到调用方法判断是否是设置配置方法 - if("addHeader".equals(selectExpressionTree.identifier().name()) || "setHeader".equals(selectExpressionTree.identifier().name())){ - //获取方法参数 + if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) { + MemberSelectExpressionTree selectExpressionTree = (MemberSelectExpressionTree) expressionTree; + if("addHeader".equals(selectExpressionTree.identifier().name()) || "setHeader".equals(selectExpressionTree.identifier().name())) { Arguments arguments = methodInvocationTree.arguments(); - if(arguments instanceof ArgumentListTreeImpl){ - boolean one = false; - boolean two = false; - for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { - if(argument instanceof LiteralTreeImpl){ - LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; - //判断参数 - if("\"X-Frame-Options\"".equals(literalTree.token().text())){ - one = true; - }else if("\"DENY\"".equals(literalTree.token().text())){ - two = true; - } + boolean one = false; + boolean two = false; + for (ExpressionTree argument : arguments) { + if(argument.is(Tree.Kind.STRING_LITERAL)){ + String literalValue = ((LiteralTree) argument).value(); + if ("\"X-Frame-Options\"".equals(literalValue)) { + one = true; + } else if("\"DENY\"".equals(literalValue)){ + two = true; } } - if(one && two){ - boo = false; - } + } + if(one && two){ + boo = false; } } } @@ -82,9 +65,8 @@ public class OptionsVerifyChecker extends IssuableSubscriptionVisitor implements @Override public void endOfAnalysis(ModuleScannerContext context) { - var defaultContext = (DefaultModuleScannerContext) context; if(boo){ - defaultContext.addIssueOnProject(this, "应设置X-Frame-Options的值为deny"); + context.addIssueOnProject(this, "应设置X-Frame-Options的值为deny"); } } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordRegexCheck.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordRegexCheck.java index c1524d7..4288040 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordRegexCheck.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordRegexCheck.java @@ -18,66 +18,82 @@ import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.*; import java.util.*; +import java.util.stream.Collectors; @Rule(key = "PasswordRegexCheck") public class PasswordRegexCheck extends IssuableSubscriptionVisitor { - private static final String MATCHER_METHOD = "matcher"; - private static final String PASSWORD_PARAMETER = "password"; - @Override public List nodesToVisit() { + // 在这里,我们只考虑方法 return Collections.singletonList(Tree.Kind.METHOD); } @Override public void visitNode(Tree tree) { - if (tree.is(Tree.Kind.METHOD)) { - MethodTree methodTree = (MethodTree) tree; - checkPasswordValidation(methodTree); + MethodTree method = (MethodTree) tree; + // 检查是否存在名为 “password”的参数 + List passwordParameters = method.parameters().stream() + .filter(param -> "password".equals(param.simpleName().name())) + .collect(Collectors.toList()); + + if (!passwordParameters.isEmpty()) { + // 确认参数 "password" 是否在正确的正则表达式之下被检查 + boolean passwordIsCheckedWithRegex = passwordParameters.stream() + .anyMatch(param -> isPasswordValidatedWithRegex(method, param)); + + if (!passwordIsCheckedWithRegex) { + reportIssue(method.simpleName(), "未对口令进行复杂度验证"); + } } } - private void checkPasswordValidation(MethodTree methodTree) { - boolean hasPasswordValidation = false; - - for (StatementTree statement : methodTree.block().body()) { - if (statement.is(Tree.Kind.VARIABLE)) { - VariableTree variableTree = (VariableTree) statement; - if (variableTree.initializer() != null && variableTree.initializer().is(Tree.Kind.METHOD_INVOCATION)) { - MethodInvocationTree methodInvocationTree = (MethodInvocationTree) variableTree.initializer(); - String methodName = methodInvocationTree.methodSymbol().name(); - if (MATCHER_METHOD.equals(methodName)) { - hasPasswordValidation = hasPasswordValidation || hasPasswordParameter(methodInvocationTree.arguments()); - } - } + + private boolean isPasswordValidatedWithRegex(Tree tree, VariableTree passwordParameter) { + PasswordValidationVisitor visitor = new PasswordValidationVisitor(passwordParameter); + tree.accept(visitor); + return visitor.isPasswordValidated(); + } + + private static class PasswordValidationVisitor extends BaseTreeVisitor { + + private final VariableTree passwordParameter; + private boolean passwordValidated = false; + + PasswordValidationVisitor(VariableTree passwordParameter) { + this.passwordParameter = passwordParameter; + } + + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + // 改变行为,查找是否存在匹配指定方法调用模式的表达式 + if (isCorrectPasswordValidationMethod(tree)) { + passwordValidated = true; } + super.visitMethodInvocation(tree); } - if (!hasPasswordValidation) { - //如果没有发现密码验证,报告问题 - System.out.println("未对口令进行复杂度验证"+methodTree.simpleName()); - reportIssue(methodTree.simpleName(), "未对口令进行复杂度验证"); + public boolean isPasswordValidated() { + return passwordValidated; } - } - private boolean hasPasswordParameter(List arguments) { - for (ExpressionTree argument : arguments) { - if (argument.is(Tree.Kind.IDENTIFIER)) { - IdentifierTree identifier = (IdentifierTree) argument; - if (PASSWORD_PARAMETER.equalsIgnoreCase(identifier.name())) { - //检查标识符是否有密码验证 - return hasPasswordValidationInMethod(identifier.name()); + private boolean isCorrectPasswordValidationMethod(MethodInvocationTree mit) { + if ("matches".equals(mit.methodSymbol().name()) + && mit.methodSelect().is(Tree.Kind.MEMBER_SELECT) + && ((MemberSelectExpressionTree) mit.methodSelect()).identifier().name().equals("matcher") + && ((MemberSelectExpressionTree) mit.methodSelect()).expression().is(Tree.Kind.METHOD_INVOCATION)) { + + MethodInvocationTree innerMit = (MethodInvocationTree) ((MemberSelectExpressionTree) mit.methodSelect()).expression(); + if ("compile".equals(innerMit.methodSymbol().name()) + && innerMit.methodSelect().is(Tree.Kind.MEMBER_SELECT) + && "Pattern".equals( ((MemberSelectExpressionTree)innerMit.methodSelect()).expression().toString())) { + // 需要确定参数中包含名为 'password' 的参数 + List arguments = mit.methodSymbol().declaration().parameters().stream().filter(param -> param.symbol().name().equals("password")).collect(Collectors.toList()); + return (!arguments.isEmpty()); } } + return false; } - - return false; - } - - private boolean hasPasswordValidationInMethod(String paramName) { - //参数名是'password',已经存在 - return PASSWORD_PARAMETER.equalsIgnoreCase(paramName); } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java index c4652d0..e0c6bda 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java @@ -7,9 +7,6 @@ package com.keyware.sonar.java.rules.checkers; import org.sonar.check.Rule; -import org.sonar.java.ast.parser.ArgumentListTreeImpl; -import org.sonar.java.model.InternalSyntaxToken; -import org.sonar.java.model.expression.LiteralTreeImpl; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.*; @@ -39,28 +36,19 @@ public class RSAEncryptionChecker extends IssuableSubscriptionVisitor { public void visitNode(Tree tree) { MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; ExpressionTree expressionTree = methodInvocationTree.methodSelect(); -// 获取到方法调用 - if(expressionTree instanceof MemberSelectExpressionTree){ + // 获取到方法调用 + if (expressionTree instanceof MemberSelectExpressionTree) { MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree; -// 判断是否符合标准 - if("Cipher".equals(memberSelectExpressionTree.expression().toString()) && "getInstance".equals(memberSelectExpressionTree.identifier().name())){ -// 获取参数列表 - Arguments arguments = methodInvocationTree.arguments(); - if(arguments instanceof ArgumentListTreeImpl){ -// 获取到参数列表 - ArgumentListTreeImpl argumentListTree = (ArgumentListTreeImpl) arguments; - for (ExpressionTree argument : argumentListTree) { - if(argument instanceof LiteralTreeImpl){ - LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; -// 获取到其中的参数 - SyntaxToken syntaxToken = literalTree.token(); - if(syntaxToken instanceof InternalSyntaxToken){ - InternalSyntaxToken internalSyntaxToken = (InternalSyntaxToken) syntaxToken; -// 对参数进行判断判断是否符合要求 - if(!(internalSyntaxToken.text().startsWith("\"RSA") && internalSyntaxToken.text().contains("OAEPWithSHA-256AndMGF1Padding"))){ - context.reportIssue(this,tree,"使用RSA最优加密填充"); - } - } + // 判断是否符合标准 + if ("Cipher".equals(memberSelectExpressionTree.expression().toString()) && "getInstance".equals(memberSelectExpressionTree.identifier().name())) { + // 获取参数列表 + List arguments = methodInvocationTree.arguments(); + for (ExpressionTree argument : arguments) { + if (argument.is(Tree.Kind.STRING_LITERAL)) { + LiteralTree literalTree = (LiteralTree) argument; + // 对参数进行判断判断是否符合要求 + if (!(literalTree.value().startsWith("\"RSA") && literalTree.value().contains("OAEPWithSHA-256AndMGF1Padding"))) { + context.reportIssue(this, tree, "使用RSA最优加密填充"); } } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SendMessageVerifyChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SendMessageVerifyChecker.java index ac0d253..e67f9dd 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SendMessageVerifyChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SendMessageVerifyChecker.java @@ -8,9 +8,6 @@ package com.keyware.sonar.java.rules.checkers; import org.sonar.check.Rule; -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.*; @@ -48,10 +45,10 @@ public class SendMessageVerifyChecker extends IssuableSubscriptionVisitor { @Override public void visitNode(Tree tree) { - MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) tree; + MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; ExpressionTree expressionTree = methodInvocationTree.methodSelect(); - if(expressionTree instanceof IdentifierTreeImpl){ - IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree; + if(expressionTree.is(Tree.Kind.IDENTIFIER)){ + IdentifierTree identifierTree = (IdentifierTree) expressionTree; //判断方法是否是方法调用的节点 if(identifierTree.name().toLowerCase().contains("send")){ IdenVisitor idenVisitor = new IdenVisitor(this); @@ -73,7 +70,6 @@ public class SendMessageVerifyChecker extends IssuableSubscriptionVisitor { checker.context.reportIssue(checker, tree, "发送信息规则检查"); } } - } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsChecker.java index 3ba3571..e4351ab 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsChecker.java @@ -7,16 +7,10 @@ package com.keyware.sonar.java.rules.checkers; import org.sonar.check.Rule; -import org.sonar.java.ast.parser.ArgumentListTreeImpl; -import org.sonar.java.model.expression.LiteralTreeImpl; -import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.semantic.Symbol; import org.sonar.plugins.java.api.semantic.Type; -import org.sonar.plugins.java.api.tree.Arguments; -import org.sonar.plugins.java.api.tree.ExpressionTree; -import org.sonar.plugins.java.api.tree.MethodInvocationTree; -import org.sonar.plugins.java.api.tree.Tree; +import org.sonar.plugins.java.api.tree.*; import javax.annotation.Nonnull; import java.util.List; @@ -47,38 +41,33 @@ public class SessionCacheParamsChecker extends IssuableSubscriptionVisitor { @Override public void visitNode(@Nonnull Tree tree) { - // ((MemberSelectExpressionTree)methodInvocationTree.methodSelect()).expression().symbolType() MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; - Symbol.MethodSymbol methodSymbol = methodInvocationTree.methodSymbol(); - if(methodSymbol.isMethodSymbol()) { - //获取参数 - ExpressionTree expressionTree = methodInvocationTree.methodSelect(); - if(expressionTree instanceof MemberSelectExpressionTreeImpl){ - MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; - //获取参数类型 - Type type = selectExpressionTree.expression().symbolType(); - if(type != null){ - //判断参数类型和调用方法符不符合要求 - if(requestType.equals(type.fullyQualifiedName()) - && ("getParameter".equals(methodSymbol.name()) || "getCookies".equals(methodSymbol.name()))) { - //如果是getCookies方法直接抛错 - if("getCookies".equals(methodSymbol.name())){ - reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取"); - }else { - //获取参数 - Arguments arguments = methodInvocationTree.arguments(); - if(arguments instanceof ArgumentListTreeImpl){ - for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { - if(argument instanceof LiteralTreeImpl){ - LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; - //获取参数值 - String name = literalTree.token().text().replace("\"", "").toLowerCase(); - //判断是否是违规项 - if(HIDED_PARAMS.contains(name)){ - reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取"); - break; - } - } + Symbol.MethodSymbol methodSymbol = (Symbol.MethodSymbol) methodInvocationTree.methodSymbol(); + //获取参数 + ExpressionTree expressionTree = methodInvocationTree.methodSelect(); + if(expressionTree.is(Tree.Kind.MEMBER_SELECT)){ + MemberSelectExpressionTree selectExpressionTree = (MemberSelectExpressionTree) expressionTree; + //获取参数类型 + Type type = selectExpressionTree.expression().symbolType(); + if(type != null){ + //判断参数类型和调用方法符不符合要求 + if(requestType.equals(type.fullyQualifiedName()) + && ("getParameter".equals(methodSymbol.name()) || "getCookies".equals(methodSymbol.name()))) { + //如果是getCookies方法直接抛错 + if("getCookies".equals(methodSymbol.name())){ + reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取"); + }else { + //获取参数 + Arguments arguments = methodInvocationTree.arguments(); + for (ExpressionTree argument : arguments) { + if(argument.is(Tree.Kind.STRING_LITERAL)){ + String name = ((LiteralTree) argument).value() + .replace("\"", "").toLowerCase(); + //判断是否是违规项 + if(HIDED_PARAMS.contains(name)){ + System.out.println(methodInvocationTree); + reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取"); + break; } } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java index 9394a5a..4c57bf1 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java @@ -47,27 +47,34 @@ public class UpperCycleLimitRuleChecker extends IssuableSubscriptionVisitor { @Override public void visitForStatement(ForStatementTree fnode) { - var ffnode = fnode.condition(); - if (ffnode instanceof BinaryExpressionTreeImpl) { - ExpressionTree leftOperand = ((BinaryExpressionTreeImpl) ffnode).leftOperand(); + ExpressionTree ffnode = fnode.condition(); + if (ffnode.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO, Tree.Kind.LESS_THAN, Tree.Kind.LESS_THAN_OR_EQUAL_TO, Tree.Kind.GREATER_THAN, Tree.Kind.GREATER_THAN_OR_EQUAL_TO)) { + BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) ffnode; + ExpressionTree leftOperand = binaryExpressionTree.leftOperand(); checkVar(leftOperand); - ExpressionTree rightOperand = ((BinaryExpressionTreeImpl) ffnode).rightOperand(); + ExpressionTree rightOperand = binaryExpressionTree.rightOperand(); checkVar(rightOperand); } } @Override public void visitWhileStatement(WhileStatementTree wnode) { - var wwnode = wnode.condition(); - ExpressionTree teea = ((BinaryExpressionTreeImpl) wwnode).leftOperand(); - checkVar(teea); + ExpressionTree wwnode = wnode.condition(); + if (wwnode.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO, Tree.Kind.LESS_THAN, Tree.Kind.LESS_THAN_OR_EQUAL_TO, Tree.Kind.GREATER_THAN, Tree.Kind.GREATER_THAN_OR_EQUAL_TO)) { + BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) wwnode; + ExpressionTree leftOperand = binaryExpressionTree.leftOperand(); + checkVar(leftOperand); + } } @Override public void visitDoWhileStatement(DoWhileStatementTree dnode) { - var ddnode = dnode.condition(); - ExpressionTree teeas = ((BinaryExpressionTreeImpl) ddnode).leftOperand(); - checkVar(teeas); + ExpressionTree ddnode = dnode.condition(); + if (ddnode.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO, Tree.Kind.LESS_THAN, Tree.Kind.LESS_THAN_OR_EQUAL_TO, Tree.Kind.GREATER_THAN, Tree.Kind.GREATER_THAN_OR_EQUAL_TO)) { + BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) ddnode; + ExpressionTree leftOperand = binaryExpressionTree.leftOperand(); + checkVar(leftOperand); + } } diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UserStatusVerifyChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UserStatusVerifyChecker.java index 13a430b..4d2a456 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UserStatusVerifyChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UserStatusVerifyChecker.java @@ -8,10 +8,6 @@ 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.LiteralTreeImpl; -import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.*; @@ -45,6 +41,7 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor { if(visitMethod.booOne && visitMethod.booTwo && visitMethod.booThree && visitMethod.booFour){ }else{ + System.out.println(methodTree.simpleName()); context.reportIssue(this, methodTree.simpleName(), "对用户进行身份鉴别并建立一个新的会话时让原来的会话失效"); } @@ -57,12 +54,8 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor { //获取参数 List parameters = methodTree.parameters(); for (VariableTree variable : parameters) { - if (variable instanceof VariableTreeImpl) { - //判断参数是否有ServletRequest - VariableTreeImpl variableTree = (VariableTreeImpl) variable; - if (variableTree.type().toString().endsWith("ServletRequest")) { - return true; - } + if (variable.type().symbolType().name().endsWith("ServletRequest")) { + return true; } } } @@ -86,9 +79,9 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor { @Override public void visitMethodInvocation(MethodInvocationTree tree) { ExpressionTree expressionTree = tree.methodSelect(); - if(expressionTree instanceof MemberSelectExpressionTreeImpl){ + if(expressionTree.is(Tree.Kind.MEMBER_SELECT)){ //判断是否调用指定的方法 - MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; + MemberSelectExpressionTree selectExpressionTree = (MemberSelectExpressionTree) expressionTree; if("getParameter".equals(selectExpressionTree.identifier().name()) || "getSession".equals(selectExpressionTree.identifier().name())){ //获取到调用方法的参数 Arguments arguments = tree.arguments(); @@ -101,18 +94,16 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor { } public void verifyParam(Arguments arguments){ - if(arguments instanceof ArgumentListTreeImpl){ - for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { - if(argument instanceof LiteralTreeImpl){ - LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; - String strName = literalTree.token().text().replace("\"", "").toLowerCase(); - if("username".equals(strName)){ - booOne = true; - }else if("password".equals(strName)){ - booTwo = true; - }else if("false".equals(strName)){ - booThree = true; - } + for (ExpressionTree argument : arguments) { + if(argument.is(Tree.Kind.STRING_LITERAL)){ + LiteralTree literalTree = (LiteralTree) argument; + String strName = literalTree.value().replace("\"", "").toLowerCase(); + if("username".equals(strName)){ + booOne = true; + }else if("password".equals(strName)){ + booTwo = true; + }else if("false".equals(strName)){ + booThree = true; } } }