修改部分规则bug

master
wuhaoyang 7 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.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, "应通过用户名口令、数据证书等其他手段对用户身份进行验证");
}
}
}

@ -30,7 +30,7 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor {
@Override
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
@ -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参数设置中包含敏感字段");
}
}
}

@ -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;

@ -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<Tree> 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;
}
}
}

@ -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语句前应对其进行验证");
}
}
}

@ -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();
}
}

@ -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<Tree.Kind> 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");
}
}
}

@ -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<Tree.Kind> 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<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;
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<ExpressionTree> 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<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;
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<ExpressionTree> 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最优加密填充");
}
}
}

@ -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, "发送信息规则检查");
}
}
}
}

@ -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;
}
}
}

@ -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);
}
}

@ -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<VariableTree> 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;
}
}
}

Loading…
Cancel
Save