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 new file mode 100644 index 0000000..4af1927 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HttpInputDataChecker.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:Java 信息安全性设计准则 + * 项目描述:用于检查Java源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ +package com.keyware.sonar.java.rules.checkers; + +import org.sonar.check.Rule; +import org.sonar.java.ast.parser.ArgumentListTreeImpl; +import org.sonar.java.model.expression.AssignmentExpressionTreeImpl; +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.Collections; +import java.util.List; + +/** + * TODO HttpInputDataChecker + * + * @author RenFengJiang + * @date 2024/1/12 + */ +@Rule(key = "HttpInputDataChecker") +public class HttpInputDataChecker extends IssuableSubscriptionVisitor { + @Override + public List nodesToVisit() { + /** + * Tree.Kind.METHOD:方法节点 + * Tree.Kind.BLOCK:方法的代码块节点 + * Tree.Kind.METHOD_INVOCATION: 方法的调用节点 + */ + return Collections.singletonList(Tree.Kind.BLOCK); + } + @Override + public void visitNode(Tree tree) { + BlockTree blockTree = (BlockTree) tree; + MethodBodyVisitor methodBodyVisitor = new MethodBodyVisitor(this); + blockTree.accept(methodBodyVisitor); + + } + + static class MethodBodyVisitor extends BaseTreeVisitor{ + private final HttpInputDataChecker checker; + List list = new ArrayList<>(); + MethodBodyVisitor(HttpInputDataChecker checker){ + this.checker = checker; + } + + @Override + public void visitIfStatement(IfStatementTree tree) { + System.out.println(tree); + ExpressionTree condition = tree.condition(); + System.out.println(condition.toString()); + if(condition instanceof AssignmentExpressionTreeImpl){ + AssignmentExpressionTreeImpl assignmentExpressionTree = (AssignmentExpressionTreeImpl) condition; + list.add(assignmentExpressionTree.variable().toString()); + } + } + + @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())){ + 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; + } + } + } + } + } + } + } + + + + + } +} diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HttpInputDataChecker.html b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HttpInputDataChecker.html new file mode 100644 index 0000000..e18fed3 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HttpInputDataChecker.html @@ -0,0 +1,9 @@ +

HTTP输入数据验证

+

在写入HTTP响应的报头前对输入数据进行验证或编码,确保输入数据不包含回车换行字符。

+
+
+
+

合规解决方案

+
+
+
diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HttpInputDataChecker.json b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HttpInputDataChecker.json new file mode 100644 index 0000000..2109659 --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HttpInputDataChecker.json @@ -0,0 +1,13 @@ +{ + "title": "HTTP输入数据验证", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "28suo" + ], + "defaultSeverity": "Minor" +} \ No newline at end of file diff --git a/sonar-keyware-plugins-java/src/test/files/HttpInputDataRule.java b/sonar-keyware-plugins-java/src/test/files/HttpInputDataRule.java new file mode 100644 index 0000000..75e50ab --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/files/HttpInputDataRule.java @@ -0,0 +1,25 @@ + +public class HttpInputDataRule { + public static void main(String[] args) { + // 假设有一个HttpServletResponse对象 + HttpServletResponse response = new HttpServletResponse(); + + // 设置单个报头 + response.setHeader("Content-Type", "text/plain"); // Noncompliant {{HTTP输入数据验证}} + + // 添加多个报头 + String a = "Cache-Control"; + String b = "no-cache" ; + if(a = "asds"){ + + } + if(b = "asds"){ + + } + + response.addHeader(a, b); +// response.addHeader("X-Custom-Header", "Custom Value"); + + // 其他操作... + } +} diff --git a/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/HttpInputDataCheckerTest.java b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/HttpInputDataCheckerTest.java new file mode 100644 index 0000000..17e85f1 --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/HttpInputDataCheckerTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:Java 信息安全性设计准则 + * 项目描述:用于检查Java源代码的安全性设计准则的Sonarqube插件 + * 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 + */ +package com.keyware.sonar.java.rules.checkers; + +import com.keyware.sonar.java.utils.FilesUtils; +import org.junit.jupiter.api.Test; +import org.sonar.java.checks.verifier.CheckVerifier; + +/** + * TODO HttpInputDataCheckerTest + * + * @author RenFengJiang + * @date 2024/1/12 + */ +public class HttpInputDataCheckerTest { + @Test + void detected() { + HttpInputDataChecker rule = new HttpInputDataChecker(); + + + CheckVerifier.newVerifier() + .onFile("src/test/files/HttpInputDataRule.java") + .withCheck(rule) + .withClassPath(FilesUtils.getClassPath("target/test-jars")) + .verifyIssues(); + } +}