From c70be3539fc62240a8cce1621ab83dd91c790935 Mon Sep 17 00:00:00 2001 From: RenFengJiang <1111> Date: Wed, 24 Jan 2024 19:23:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9Ajava=E5=B0=86?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E9=9A=90=E8=97=8F=E5=9F=9F=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E3=80=81Cookie=E3=80=81URL=E7=AD=89=E5=85=B3=E9=94=AE=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BC=93=E5=AD=98=E5=88=B0=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E4=BC=9A=E8=AF=9D=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../checkers/SessionCacheParamsChecker.java | 60 +++++++++++++++++-- .../rules/java/SessionCacheParamsChecker.html | 16 +++++ .../rules/java/SessionCacheParamsChecker.json | 13 ++++ .../test/files/SessionCacheParamsChecker.java | 27 ++++++--- .../SessionCacheParamsCheckerTest.java | 29 +++++++++ 5 files changed, 130 insertions(+), 15 deletions(-) create mode 100644 sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.html create mode 100644 sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.json create mode 100644 sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsCheckerTest.java 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 136ee9d..3ba3571 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,7 +7,15 @@ 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 javax.annotation.Nonnull; @@ -22,11 +30,15 @@ import java.util.List; */ @Rule(key = "SessionCacheParamsChecker") public class SessionCacheParamsChecker extends IssuableSubscriptionVisitor { + + //违规集合 private static final List HIDED_PARAMS = List.of( - "id", - "token" + "userid", + "token", + "url", + "userpassword" ); - + private static final String requestType = "javax.servlet.http.HttpServletRequest"; @Override public List nodesToVisit() { @@ -35,8 +47,44 @@ 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; + } + } + } + } + } + } + } + } + } } - - } diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.html b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.html new file mode 100644 index 0000000..cd92f6f --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.html @@ -0,0 +1,16 @@ + + +

页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取

+

页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取

+
+
+
+

合规解决方案

+
+
+
diff --git a/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.json b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.json new file mode 100644 index 0000000..164cbab --- /dev/null +++ b/sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.json @@ -0,0 +1,13 @@ +{ + "title": "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取", + "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/SessionCacheParamsChecker.java b/sonar-keyware-plugins-java/src/test/files/SessionCacheParamsChecker.java index 34f4d6a..55bac41 100644 --- a/sonar-keyware-plugins-java/src/test/files/SessionCacheParamsChecker.java +++ b/sonar-keyware-plugins-java/src/test/files/SessionCacheParamsChecker.java @@ -1,22 +1,31 @@ -package com.example; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.*; + public class ExampleServlet extends HttpServlet { + private static final long serialVersionUID = 1391640560504378168L; + public void doGet(HttpServletRequest request, HttpServletResponse response) { // 直接从request获取参数 - String param = request.getParameter("userId"); // Noncompliant {{建议将页面隐藏域字段、Cookie、URL等关键参数缓存到服务器端的会话中,并通过会话获取}} - + String param = request.getParameter("userId"); // Noncompliant {{页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取}} + request.getParameter("userpassword");// Noncompliant {{页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取}} + request.getParameter("token");// Noncompliant {{页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取}} + request.getParameter("url");// Noncompliant {{页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取}} // 直接从request获取Cookies - Cookie[] cookies = request.getCookies(); + Cookie[] cookies = request.getCookies();// Noncompliant {{页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取}} // 将参数存储到session HttpSession session = request.getSession(); session.setAttribute("sessionParam", param); // 其他代码... } - private void get(HttpServletRequest request, HttpServletResponse response){ + @RestController + class TestController{ + @GetMapping("/get") + public void get(HttpServletRequest request){ + String userId = request.getParameter("userId");// Noncompliant {{页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取}} + } } } \ No newline at end of file diff --git a/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsCheckerTest.java b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsCheckerTest.java new file mode 100644 index 0000000..6a17a9a --- /dev/null +++ b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsCheckerTest.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. + * 项目名称:信息安全性设计准则检查插件 + * 项目描述:用于检查源代码的安全性设计准则的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 SessionCacheParamsCheckerTest + * + * @author RenFengJiang + * @date 2024/1/24 + */ +public class SessionCacheParamsCheckerTest { + @Test + public void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/SessionCacheParamsChecker.java") + .withCheck(new SessionCacheParamsChecker()) + .withClassPath(FilesUtils.getClassPath("target/test-jars")) + .verifyIssues(); + } +}