修改部分规则bug

master
wuhaoyang 9 months ago
parent 3a92071b20
commit 14b4286761
  1. 4
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/AuthenticationChecker.java
  2. 18
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/CookieSensitiveParameterCheck.java
  3. 33
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java
  4. 48
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HttpInputDataChecker.java
  5. 25
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/InputSQLVerifyChecker.java
  6. 48
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyChecker.java
  7. 58
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java
  8. 92
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordRegexCheck.java
  9. 36
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java
  10. 10
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SendMessageVerifyChecker.java
  11. 65
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsChecker.java
  12. 27
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java
  13. 39
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UserStatusVerifyChecker.java

@ -8,7 +8,6 @@ package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; import org.sonar.check.Rule;
import org.sonar.java.model.DefaultModuleScannerContext;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.ModuleScannerContext; import org.sonar.plugins.java.api.ModuleScannerContext;
import org.sonar.plugins.java.api.internal.EndOfAnalysis; import org.sonar.plugins.java.api.internal.EndOfAnalysis;
@ -99,10 +98,9 @@ public class AuthenticationChecker extends IssuableSubscriptionVisitor implement
@Override @Override
public void endOfAnalysis(ModuleScannerContext context) { public void endOfAnalysis(ModuleScannerContext context) {
var defaultContext = (DefaultModuleScannerContext) context;
if (!isValidPathFound) { if (!isValidPathFound) {
System.out.println("应通过用户名口令、数据证书等其他手段对用户身份进行验证"); System.out.println("应通过用户名口令、数据证书等其他手段对用户身份进行验证");
defaultContext.addIssueOnProject(this, "应通过用户名口令、数据证书等其他手段对用户身份进行验证"); context.addIssueOnProject(this, "应通过用户名口令、数据证书等其他手段对用户身份进行验证");
} }
} }
} }

@ -30,7 +30,7 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor {
@Override @Override
public List<Tree.Kind> nodesToVisit() { public List<Tree.Kind> 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 @Override
@ -39,8 +39,6 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor {
visitMethodInvocation((MethodInvocationTree) tree); visitMethodInvocation((MethodInvocationTree) tree);
} else if (tree.is(Tree.Kind.VARIABLE)) { } else if (tree.is(Tree.Kind.VARIABLE)) {
visitVariable((VariableTree) tree); 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); System.out.println("Cookie参数设置中的value属性与局部变量一致: " + variableName);
reportIssue(expression, "Cookie参数设置中包含敏感字段"); reportIssue(expression, "Cookie参数设置中包含敏感字段");
} }
} } else if (expression.is(Tree.Kind.STRING_LITERAL)) {
} String literalValue = LiteralTree.class.cast(expression).value();
if (containsSensitiveParam(literalValue)) {
private void visitStringLiteral(LiteralTree literalTree) { System.out.println("Cookie参数设置中的name属性包含敏感字符串: " + literalValue);
String literalValue = literalTree.value(); reportIssue(expression, "Cookie参数设置中包含敏感字段");
if (containsSensitiveParam(literalValue)) { }
System.out.println("Cookie参数设置中包含敏感字段: " + literalValue);
reportIssue(literalTree, "Cookie参数设置中包含敏感字段");
} }
} }

@ -10,7 +10,6 @@ import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl; import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.declaration.VariableTreeImpl; import org.sonar.java.model.declaration.VariableTreeImpl;
import org.sonar.java.model.expression.IdentifierTreeImpl; import org.sonar.java.model.expression.IdentifierTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.java.model.expression.MethodInvocationTreeImpl; import org.sonar.java.model.expression.MethodInvocationTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*; import org.sonar.plugins.java.api.tree.*;
@ -56,28 +55,26 @@ public class HashSaltPassWordChecker extends IssuableSubscriptionVisitor {
@Override @Override
public void visitMethodInvocation(MethodInvocationTree tree) { public void visitMethodInvocation(MethodInvocationTree tree) {
// 获取到方法调用 //获取到方法调用
ExpressionTree expressionTree = tree.methodSelect(); ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree instanceof MemberSelectExpressionTreeImpl) { if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
// 获取到调用的方法 // 获取到调用的方法
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if ("setPassWord".equals(memberSelectExpressionTree.identifier().name())) { if ("setPassWord".equals(memberSelectExpressionTree.identifier().name())) {
Tree parent = tree.arguments(); Arguments arguments = tree.arguments();
if (parent instanceof ArgumentListTreeImpl) { for (ExpressionTree expressionTree1 : arguments) {
for (ExpressionTree expressionTree1 : (ArgumentListTreeImpl) parent) { if (expressionTree1.is(Tree.Kind.IDENTIFIER)) {
if (expressionTree1 instanceof IdentifierTreeImpl) { IdentifierTree identifierTree = (IdentifierTree) expressionTree1;
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree1; // 判断set中使用的参数
// 判断set中使用的参数 if(!identifierTree.name().equals(strPassWord)){
if(!identifierTree.name().equals(strPassWord)){ checker.context.reportIssue(checker, identifierTree, "应使用盐值计算口令");
checker.context.reportIssue(checker, identifierTree, "应使用盐值计算口令");
}
}else {
checker.context.reportIssue(checker, expressionTree1, "应使用盐值计算口令");
} }
} 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(); Tree parent = memberSelectExpressionTree.parent();
if(parent instanceof MethodInvocationTreeImpl){ if(parent instanceof MethodInvocationTreeImpl){
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) parent; MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) parent;

@ -7,15 +7,11 @@
package com.keyware.sonar.java.rules.checkers; package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; 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.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*; import org.sonar.plugins.java.api.tree.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -54,12 +50,12 @@ public class HttpInputDataChecker extends IssuableSubscriptionVisitor {
@Override @Override
public void visitIfStatement(IfStatementTree tree) { public void visitIfStatement(IfStatementTree tree) {
ExpressionTree condition = tree.condition(); ExpressionTree condition = tree.condition();
if (condition instanceof BinaryExpressionTreeImpl) { if (condition.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO)) {
BinaryExpressionTreeImpl binaryExpressionTree = (BinaryExpressionTreeImpl) condition; BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) condition;
List<Tree> children = binaryExpressionTree.children();
for (Tree child:children) { for (Tree operand : Arrays.asList(binaryExpressionTree.leftOperand(), binaryExpressionTree.rightOperand())) {
if(child instanceof IdentifierTreeImpl){ if (operand.is(Tree.Kind.IDENTIFIER)) {
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) child; IdentifierTree identifierTree = (IdentifierTree) operand;
list.add(identifierTree.name()); list.add(identifierTree.name());
} }
} }
@ -69,24 +65,20 @@ public class HttpInputDataChecker extends IssuableSubscriptionVisitor {
@Override @Override
public void visitMethodInvocation(MethodInvocationTree tree) { public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect(); ExpressionTree expressionTree = tree.methodSelect();
if(expressionTree instanceof MemberSelectExpressionTreeImpl){ if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if("setHeader".equals(memberSelectExpressionTree.identifier().name()) || "addHeader".equals(memberSelectExpressionTree.identifier().name())){ if ("setHeader".equals(memberSelectExpressionTree.identifier().name())
|| "addHeader".equals(memberSelectExpressionTree.identifier().name())) {
Arguments arguments = tree.arguments(); Arguments arguments = tree.arguments();
if(arguments instanceof ArgumentListTreeImpl){ for (ExpressionTree argument : arguments) {
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { if(argument.is(Tree.Kind.STRING_LITERAL)){
if(argument instanceof LiteralTreeImpl){ checker.context.reportIssue(checker, argument, "HTTP输入数据验证");
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; break;
if("STRING_LITERAL".equals(literalTree.kind().name())){ } else if(argument.is(Tree.Kind.IDENTIFIER)){
checker.context.reportIssue(checker, literalTree, "HTTP输入数据验证"); IdentifierTree identifierTree = (IdentifierTree) argument;
break; if(!list.contains(identifierTree.name())){
} checker.context.reportIssue(checker, identifierTree, "HTTP输入数据验证");
}else if(argument instanceof IdentifierTreeImpl){ break;
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) argument;
if(!list.contains(identifierTree.name())){
checker.context.reportIssue(checker, identifierTree, "HTTP输入数据验证");
break;
}
} }
} }
} }

@ -7,9 +7,6 @@
package com.keyware.sonar.java.rules.checkers; package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; 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.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*; import org.sonar.plugins.java.api.tree.*;
@ -64,19 +61,17 @@ public class InputSQLVerifyChecker extends IssuableSubscriptionVisitor {
@Override @Override
public void visitMethodInvocation(MethodInvocationTree tree) { public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect(); ExpressionTree expressionTree = tree.methodSelect();
if(expressionTree instanceof MemberSelectExpressionTreeImpl){ if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if("prepareStatement".equals(memberSelectExpressionTree.identifier().name())){ if ("prepareStatement".equals(memberSelectExpressionTree.identifier().name())) {
Arguments arguments = tree.arguments(); Arguments arguments = tree.arguments();
if(arguments instanceof ArgumentListTreeImpl){ for (ExpressionTree argument : arguments) {
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { if (argument.is(Tree.Kind.IDENTIFIER)) {
if (argument instanceof IdentifierTreeImpl){ IdentifierTree identifierTree = (IdentifierTree) argument;
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) argument; String name = identifierTree.name();
String name = identifierTree.name(); // 判断使用的sql是否存在集合中
//判断使用的sql是否存在集合中 if (!lists.contains(name)) {
if(!lists.contains(name)){ checker.context.reportIssue(checker, argument, "使用sql语句前应对其进行验证");
checker.context.reportIssue(checker,argument,"使用sql语句前应对其进行验证");
}
} }
} }
} }

@ -7,11 +7,6 @@
package com.keyware.sonar.java.rules.checkers; package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; 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.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*; import org.sonar.plugins.java.api.tree.*;
@ -58,33 +53,34 @@ public class Md5PassWordVerifyChecker extends IssuableSubscriptionVisitor {
public void visitMethodInvocation(MethodInvocationTree tree) { public void visitMethodInvocation(MethodInvocationTree tree) {
//获取到方法调用 //获取到方法调用
ExpressionTree expressionTree = tree.methodSelect(); ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree instanceof MemberSelectExpressionTreeImpl) { if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
//获取到调用的方法 MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
if ("setPassWord".equals(memberSelectExpressionTree.identifier().name())) { if ("setPassWord".equals(memberSelectExpressionTree.identifier().name())) {
Tree parent = tree.arguments(); Arguments arguments = tree.arguments();
if (parent instanceof ArgumentListTreeImpl) { //改用arguments,这里没必要再用 instanceof 检查接口了
for (ExpressionTree expressionTree1 : (ArgumentListTreeImpl) parent) { for (ExpressionTree argument : arguments) {
if (expressionTree1 instanceof IdentifierTreeImpl) { if (argument.is(Tree.Kind.IDENTIFIER)) {
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree1; IdentifierTree identifierTree = (IdentifierTree) argument;
//判断set中使用的参数 String name = identifierTree.name();
if(!identifierTree.name().equals(strPassWord)){ if (!name.equals(strPassWord)) {
checker.context.reportIssue(checker, identifierTree, "应使用单向不可逆的加密算法"); System.out.println(identifierTree);
} checker.context.reportIssue(checker, identifierTree, "应使用单向不可逆的加密算法");
}else {
checker.context.reportIssue(checker, expressionTree1, "应使用单向不可逆的加密算法");
} }
} else {
System.out.println(argument);
checker.context.reportIssue(checker, argument, "应使用单向不可逆的加密算法");
} }
} }
//判断是否使用单向不可逆加密方式 } else if (memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("md5hex")
}else if(memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("md5hex") || memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("encrypt")){ || memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("encrypt")) {
Tree parent = memberSelectExpressionTree.parent(); Tree parent = memberSelectExpressionTree.parent();
if(parent instanceof MethodInvocationTreeImpl){ //对parent进行了instanceof检查,这是不正确的,应该使用is(Tree.Kind.SOMETHING)
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) parent; if (parent.is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) parent;
Tree parent1 = methodInvocationTree.parent(); Tree parent1 = methodInvocationTree.parent();
if(parent1 instanceof VariableTreeImpl){ //这同样是对parent1进行了instanceof检查,这是不正确的,应该使用is(Tree.Kind.SOMETHING)
VariableTreeImpl variableTree = (VariableTreeImpl) parent1; if (parent1.is(Tree.Kind.VARIABLE)) {
//获取加密后的名称 VariableTree variableTree = (VariableTree) parent1;
strPassWord = variableTree.simpleName().name(); strPassWord = variableTree.simpleName().name();
} }
} }

@ -8,17 +8,10 @@
package com.keyware.sonar.java.rules.checkers; package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; 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.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.ModuleScannerContext; import org.sonar.plugins.java.api.ModuleScannerContext;
import org.sonar.plugins.java.api.internal.EndOfAnalysis; import org.sonar.plugins.java.api.internal.EndOfAnalysis;
import org.sonar.plugins.java.api.tree.Arguments; import org.sonar.plugins.java.api.tree.*;
import org.sonar.plugins.java.api.tree.ExpressionTree;
import org.sonar.plugins.java.api.tree.Tree;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -35,45 +28,35 @@ import java.util.List;
public class OptionsVerifyChecker extends IssuableSubscriptionVisitor implements EndOfAnalysis { public class OptionsVerifyChecker extends IssuableSubscriptionVisitor implements EndOfAnalysis {
private boolean boo = true; private boolean boo = true;
@Override @Override
public List<Tree.Kind> nodesToVisit() { public List<Tree.Kind> nodesToVisit() {
/**
* Tree.Kind.METHOD方法节点
* Tree.Kind.BLOCK方法的代码块节点
* Tree.Kind.METHOD_INVOCATION 方法的调用节点
*/
return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); return Collections.singletonList(Tree.Kind.METHOD_INVOCATION);
} }
@Override @Override
public void visitNode(Tree tree) { public void visitNode(Tree tree) {
//判断项目是否配置 if(boo) {
if(boo){ MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) tree;
ExpressionTree expressionTree = methodInvocationTree.methodSelect(); ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if(expressionTree instanceof MemberSelectExpressionTreeImpl){ if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; MemberSelectExpressionTree selectExpressionTree = (MemberSelectExpressionTree) expressionTree;
//获取到调用方法判断是否是设置配置方法 if("addHeader".equals(selectExpressionTree.identifier().name()) || "setHeader".equals(selectExpressionTree.identifier().name())) {
if("addHeader".equals(selectExpressionTree.identifier().name()) || "setHeader".equals(selectExpressionTree.identifier().name())){
//获取方法参数
Arguments arguments = methodInvocationTree.arguments(); Arguments arguments = methodInvocationTree.arguments();
if(arguments instanceof ArgumentListTreeImpl){ boolean one = false;
boolean one = false; boolean two = false;
boolean two = false; for (ExpressionTree argument : arguments) {
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { if(argument.is(Tree.Kind.STRING_LITERAL)){
if(argument instanceof LiteralTreeImpl){ String literalValue = ((LiteralTree) argument).value();
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; if ("\"X-Frame-Options\"".equals(literalValue)) {
//判断参数 one = true;
if("\"X-Frame-Options\"".equals(literalTree.token().text())){ } else if("\"DENY\"".equals(literalValue)){
one = true; two = true;
}else if("\"DENY\"".equals(literalTree.token().text())){
two = true;
}
} }
} }
if(one && two){ }
boo = false; if(one && two){
} boo = false;
} }
} }
} }
@ -82,9 +65,8 @@ public class OptionsVerifyChecker extends IssuableSubscriptionVisitor implements
@Override @Override
public void endOfAnalysis(ModuleScannerContext context) { public void endOfAnalysis(ModuleScannerContext context) {
var defaultContext = (DefaultModuleScannerContext) context;
if(boo){ if(boo){
defaultContext.addIssueOnProject(this, "应设置X-Frame-Options的值为deny"); context.addIssueOnProject(this, "应设置X-Frame-Options的值为deny");
} }
} }
} }

@ -18,66 +18,82 @@ import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*; import org.sonar.plugins.java.api.tree.*;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Rule(key = "PasswordRegexCheck") @Rule(key = "PasswordRegexCheck")
public class PasswordRegexCheck extends IssuableSubscriptionVisitor { public class PasswordRegexCheck extends IssuableSubscriptionVisitor {
private static final String MATCHER_METHOD = "matcher";
private static final String PASSWORD_PARAMETER = "password";
@Override @Override
public List<Tree.Kind> nodesToVisit() { public List<Tree.Kind> nodesToVisit() {
// 在这里,我们只考虑方法
return Collections.singletonList(Tree.Kind.METHOD); return Collections.singletonList(Tree.Kind.METHOD);
} }
@Override @Override
public void visitNode(Tree tree) { public void visitNode(Tree tree) {
if (tree.is(Tree.Kind.METHOD)) { MethodTree method = (MethodTree) tree;
MethodTree methodTree = (MethodTree) tree; // 检查是否存在名为 “password”的参数
checkPasswordValidation(methodTree); List<VariableTree> 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; private boolean isPasswordValidatedWithRegex(Tree tree, VariableTree passwordParameter) {
PasswordValidationVisitor visitor = new PasswordValidationVisitor(passwordParameter);
for (StatementTree statement : methodTree.block().body()) { tree.accept(visitor);
if (statement.is(Tree.Kind.VARIABLE)) { return visitor.isPasswordValidated();
VariableTree variableTree = (VariableTree) statement; }
if (variableTree.initializer() != null && variableTree.initializer().is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) variableTree.initializer(); private static class PasswordValidationVisitor extends BaseTreeVisitor {
String methodName = methodInvocationTree.methodSymbol().name();
if (MATCHER_METHOD.equals(methodName)) { private final VariableTree passwordParameter;
hasPasswordValidation = hasPasswordValidation || hasPasswordParameter(methodInvocationTree.arguments()); 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) { public boolean isPasswordValidated() {
//如果没有发现密码验证,报告问题 return passwordValidated;
System.out.println("未对口令进行复杂度验证"+methodTree.simpleName());
reportIssue(methodTree.simpleName(), "未对口令进行复杂度验证");
} }
}
private boolean hasPasswordParameter(List<ExpressionTree> arguments) { private boolean isCorrectPasswordValidationMethod(MethodInvocationTree mit) {
for (ExpressionTree argument : arguments) { if ("matches".equals(mit.methodSymbol().name())
if (argument.is(Tree.Kind.IDENTIFIER)) { && mit.methodSelect().is(Tree.Kind.MEMBER_SELECT)
IdentifierTree identifier = (IdentifierTree) argument; && ((MemberSelectExpressionTree) mit.methodSelect()).identifier().name().equals("matcher")
if (PASSWORD_PARAMETER.equalsIgnoreCase(identifier.name())) { && ((MemberSelectExpressionTree) mit.methodSelect()).expression().is(Tree.Kind.METHOD_INVOCATION)) {
//检查标识符是否有密码验证
return hasPasswordValidationInMethod(identifier.name()); 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<VariableTree> 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);
} }
} }

@ -7,9 +7,6 @@
package com.keyware.sonar.java.rules.checkers; package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; 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.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*; import org.sonar.plugins.java.api.tree.*;
@ -39,28 +36,19 @@ public class RSAEncryptionChecker extends IssuableSubscriptionVisitor {
public void visitNode(Tree tree) { public void visitNode(Tree tree) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
ExpressionTree expressionTree = methodInvocationTree.methodSelect(); ExpressionTree expressionTree = methodInvocationTree.methodSelect();
// 获取到方法调用 // 获取到方法调用
if(expressionTree instanceof MemberSelectExpressionTree){ if (expressionTree instanceof MemberSelectExpressionTree) {
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree; MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
// 判断是否符合标准 // 判断是否符合标准
if("Cipher".equals(memberSelectExpressionTree.expression().toString()) && "getInstance".equals(memberSelectExpressionTree.identifier().name())){ if ("Cipher".equals(memberSelectExpressionTree.expression().toString()) && "getInstance".equals(memberSelectExpressionTree.identifier().name())) {
// 获取参数列表 // 获取参数列表
Arguments arguments = methodInvocationTree.arguments(); List<ExpressionTree> arguments = methodInvocationTree.arguments();
if(arguments instanceof ArgumentListTreeImpl){ for (ExpressionTree argument : arguments) {
// 获取到参数列表 if (argument.is(Tree.Kind.STRING_LITERAL)) {
ArgumentListTreeImpl argumentListTree = (ArgumentListTreeImpl) arguments; LiteralTree literalTree = (LiteralTree) argument;
for (ExpressionTree argument : argumentListTree) { // 对参数进行判断判断是否符合要求
if(argument instanceof LiteralTreeImpl){ if (!(literalTree.value().startsWith("\"RSA") && literalTree.value().contains("OAEPWithSHA-256AndMGF1Padding"))) {
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; context.reportIssue(this, tree, "使用RSA最优加密填充");
// 获取到其中的参数
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最优加密填充");
}
}
} }
} }
} }

@ -8,9 +8,6 @@
package com.keyware.sonar.java.rules.checkers; package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; 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.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*; import org.sonar.plugins.java.api.tree.*;
@ -48,10 +45,10 @@ public class SendMessageVerifyChecker extends IssuableSubscriptionVisitor {
@Override @Override
public void visitNode(Tree tree) { public void visitNode(Tree tree) {
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) tree; MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
ExpressionTree expressionTree = methodInvocationTree.methodSelect(); ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if(expressionTree instanceof IdentifierTreeImpl){ if(expressionTree.is(Tree.Kind.IDENTIFIER)){
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree; IdentifierTree identifierTree = (IdentifierTree) expressionTree;
//判断方法是否是方法调用的节点 //判断方法是否是方法调用的节点
if(identifierTree.name().toLowerCase().contains("send")){ if(identifierTree.name().toLowerCase().contains("send")){
IdenVisitor idenVisitor = new IdenVisitor(this); IdenVisitor idenVisitor = new IdenVisitor(this);
@ -73,7 +70,6 @@ public class SendMessageVerifyChecker extends IssuableSubscriptionVisitor {
checker.context.reportIssue(checker, tree, "发送信息规则检查"); checker.context.reportIssue(checker, tree, "发送信息规则检查");
} }
} }
} }
} }

@ -7,16 +7,10 @@
package com.keyware.sonar.java.rules.checkers; package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; 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.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.semantic.Symbol; import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Type; import org.sonar.plugins.java.api.semantic.Type;
import org.sonar.plugins.java.api.tree.Arguments; import org.sonar.plugins.java.api.tree.*;
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 javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.List; import java.util.List;
@ -47,38 +41,33 @@ public class SessionCacheParamsChecker extends IssuableSubscriptionVisitor {
@Override @Override
public void visitNode(@Nonnull Tree tree) { public void visitNode(@Nonnull Tree tree) {
// ((MemberSelectExpressionTree)methodInvocationTree.methodSelect()).expression().symbolType()
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
Symbol.MethodSymbol methodSymbol = methodInvocationTree.methodSymbol(); Symbol.MethodSymbol methodSymbol = (Symbol.MethodSymbol) methodInvocationTree.methodSymbol();
if(methodSymbol.isMethodSymbol()) { //获取参数
//获取参数 ExpressionTree expressionTree = methodInvocationTree.methodSelect();
ExpressionTree expressionTree = methodInvocationTree.methodSelect(); if(expressionTree.is(Tree.Kind.MEMBER_SELECT)){
if(expressionTree instanceof MemberSelectExpressionTreeImpl){ MemberSelectExpressionTree selectExpressionTree = (MemberSelectExpressionTree) expressionTree;
MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree; //获取参数类型
//获取参数类型 Type type = selectExpressionTree.expression().symbolType();
Type type = selectExpressionTree.expression().symbolType(); if(type != null){
if(type != null){ //判断参数类型和调用方法符不符合要求
//判断参数类型和调用方法符不符合要求 if(requestType.equals(type.fullyQualifiedName())
if(requestType.equals(type.fullyQualifiedName()) && ("getParameter".equals(methodSymbol.name()) || "getCookies".equals(methodSymbol.name()))) {
&& ("getParameter".equals(methodSymbol.name()) || "getCookies".equals(methodSymbol.name()))) { //如果是getCookies方法直接抛错
//如果是getCookies方法直接抛错 if("getCookies".equals(methodSymbol.name())){
if("getCookies".equals(methodSymbol.name())){ reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取");
reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取"); }else {
}else { //获取参数
//获取参数 Arguments arguments = methodInvocationTree.arguments();
Arguments arguments = methodInvocationTree.arguments(); for (ExpressionTree argument : arguments) {
if(arguments instanceof ArgumentListTreeImpl){ if(argument.is(Tree.Kind.STRING_LITERAL)){
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { String name = ((LiteralTree) argument).value()
if(argument instanceof LiteralTreeImpl){ .replace("\"", "").toLowerCase();
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; //判断是否是违规项
//获取参数值 if(HIDED_PARAMS.contains(name)){
String name = literalTree.token().text().replace("\"", "").toLowerCase(); System.out.println(methodInvocationTree);
//判断是否是违规项 reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取");
if(HIDED_PARAMS.contains(name)){ break;
reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取");
break;
}
}
} }
} }
} }

@ -47,27 +47,34 @@ public class UpperCycleLimitRuleChecker extends IssuableSubscriptionVisitor {
@Override @Override
public void visitForStatement(ForStatementTree fnode) { public void visitForStatement(ForStatementTree fnode) {
var ffnode = fnode.condition(); ExpressionTree ffnode = fnode.condition();
if (ffnode instanceof BinaryExpressionTreeImpl) { 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)) {
ExpressionTree leftOperand = ((BinaryExpressionTreeImpl) ffnode).leftOperand(); BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) ffnode;
ExpressionTree leftOperand = binaryExpressionTree.leftOperand();
checkVar(leftOperand); checkVar(leftOperand);
ExpressionTree rightOperand = ((BinaryExpressionTreeImpl) ffnode).rightOperand(); ExpressionTree rightOperand = binaryExpressionTree.rightOperand();
checkVar(rightOperand); checkVar(rightOperand);
} }
} }
@Override @Override
public void visitWhileStatement(WhileStatementTree wnode) { public void visitWhileStatement(WhileStatementTree wnode) {
var wwnode = wnode.condition(); ExpressionTree wwnode = wnode.condition();
ExpressionTree teea = ((BinaryExpressionTreeImpl) wwnode).leftOperand(); 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)) {
checkVar(teea); BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) wwnode;
ExpressionTree leftOperand = binaryExpressionTree.leftOperand();
checkVar(leftOperand);
}
} }
@Override @Override
public void visitDoWhileStatement(DoWhileStatementTree dnode) { public void visitDoWhileStatement(DoWhileStatementTree dnode) {
var ddnode = dnode.condition(); ExpressionTree ddnode = dnode.condition();
ExpressionTree teeas = ((BinaryExpressionTreeImpl) ddnode).leftOperand(); 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)) {
checkVar(teeas); BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) ddnode;
ExpressionTree leftOperand = binaryExpressionTree.leftOperand();
checkVar(leftOperand);
}
} }

@ -8,10 +8,6 @@
package com.keyware.sonar.java.rules.checkers; package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule; 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.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*; 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){ if(visitMethod.booOne && visitMethod.booTwo && visitMethod.booThree && visitMethod.booFour){
}else{ }else{
System.out.println(methodTree.simpleName());
context.reportIssue(this, methodTree.simpleName(), "对用户进行身份鉴别并建立一个新的会话时让原来的会话失效"); context.reportIssue(this, methodTree.simpleName(), "对用户进行身份鉴别并建立一个新的会话时让原来的会话失效");
} }
@ -57,12 +54,8 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor {
//获取参数 //获取参数
List<VariableTree> parameters = methodTree.parameters(); List<VariableTree> parameters = methodTree.parameters();
for (VariableTree variable : parameters) { for (VariableTree variable : parameters) {
if (variable instanceof VariableTreeImpl) { if (variable.type().symbolType().name().endsWith("ServletRequest")) {
//判断参数是否有ServletRequest return true;
VariableTreeImpl variableTree = (VariableTreeImpl) variable;
if (variableTree.type().toString().endsWith("ServletRequest")) {
return true;
}
} }
} }
} }
@ -86,9 +79,9 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor {
@Override @Override
public void visitMethodInvocation(MethodInvocationTree tree) { public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect(); 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())){ if("getParameter".equals(selectExpressionTree.identifier().name()) || "getSession".equals(selectExpressionTree.identifier().name())){
//获取到调用方法的参数 //获取到调用方法的参数
Arguments arguments = tree.arguments(); Arguments arguments = tree.arguments();
@ -101,18 +94,16 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor {
} }
public void verifyParam(Arguments arguments){ public void verifyParam(Arguments arguments){
if(arguments instanceof ArgumentListTreeImpl){ for (ExpressionTree argument : arguments) {
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) { if(argument.is(Tree.Kind.STRING_LITERAL)){
if(argument instanceof LiteralTreeImpl){ LiteralTree literalTree = (LiteralTree) argument;
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; String strName = literalTree.value().replace("\"", "").toLowerCase();
String strName = literalTree.token().text().replace("\"", "").toLowerCase(); if("username".equals(strName)){
if("username".equals(strName)){ booOne = true;
booOne = true; }else if("password".equals(strName)){
}else if("password".equals(strName)){ booTwo = true;
booTwo = true; }else if("false".equals(strName)){
}else if("false".equals(strName)){ booThree = true;
booThree = true;
}
} }
} }
} }

Loading…
Cancel
Save