新增:java将页面隐藏域字段、Cookie、URL等关键参数缓存到服务器端的会话中

wuhaoyang
RenFengJiang 10 months ago
parent 5ce8feea75
commit c70be3539f
  1. 60
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsChecker.java
  2. 16
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.html
  3. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionCacheParamsChecker.json
  4. 27
      sonar-keyware-plugins-java/src/test/files/SessionCacheParamsChecker.java
  5. 29
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsCheckerTest.java

@ -7,7 +7,15 @@
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.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.Tree;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -22,11 +30,15 @@ import java.util.List;
*/ */
@Rule(key = "SessionCacheParamsChecker") @Rule(key = "SessionCacheParamsChecker")
public class SessionCacheParamsChecker extends IssuableSubscriptionVisitor { public class SessionCacheParamsChecker extends IssuableSubscriptionVisitor {
//违规集合
private static final List<String> HIDED_PARAMS = List.of( private static final List<String> HIDED_PARAMS = List.of(
"id", "userid",
"token" "token",
"url",
"userpassword"
); );
private static final String requestType = "javax.servlet.http.HttpServletRequest";
@Override @Override
public List<Tree.Kind> nodesToVisit() { public List<Tree.Kind> nodesToVisit() {
@ -35,8 +47,44 @@ 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;
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;
}
}
}
}
}
}
}
}
}
} }
} }

@ -0,0 +1,16 @@
<!--
~ Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
~ 项目名称:信息安全性设计准则检查插件
~ 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件
~ 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
-->
<p>页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取</p>
<h2>页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取</h2>
<pre>
</pre>
<h2>合规解决方案</h2>
<pre>
</pre>

@ -0,0 +1,13 @@
{
"title": "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"28suo"
],
"defaultSeverity": "Minor"
}

@ -1,22 +1,31 @@
package com.example; import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServlet; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.*;
import javax.servlet.http.HttpSession;
public class ExampleServlet extends HttpServlet { public class ExampleServlet extends HttpServlet {
private static final long serialVersionUID = 1391640560504378168L;
public void doGet(HttpServletRequest request, HttpServletResponse response) { public void doGet(HttpServletRequest request, HttpServletResponse response) {
// 直接从request获取参数 // 直接从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 // 直接从request获取Cookies
Cookie[] cookies = request.getCookies(); Cookie[] cookies = request.getCookies();// Noncompliant {{页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取}}
// 将参数存储到session // 将参数存储到session
HttpSession session = request.getSession(); HttpSession session = request.getSession();
session.setAttribute("sessionParam", param); 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等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取}}
}
} }
} }

@ -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();
}
}
Loading…
Cancel
Save