新增:java使用sql语句前应对其进行验证

wuhaoyang
RenFengJiang 8 months ago
parent 74b8403567
commit 0087499a7e
  1. 90
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/InputSQLVerifyChecker.java
  2. 9
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/InputSQLVerifyChecker.html
  3. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/InputSQLVerifyChecker.json
  4. 37
      sonar-keyware-plugins-java/src/test/files/InputSQLVerifyRule.java
  5. 32
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/InputSQLVerifyCheckerTest.java

@ -0,0 +1,90 @@
/*
* 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.IdentifierTreeImpl;
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 InputSQLVerifyChecker
*
* @author RenFengJiang
* @date 2024/1/14
*/
@Rule(key = "InputSQLVerifyChecker")
public class InputSQLVerifyChecker extends IssuableSubscriptionVisitor {
@Override
public List<Tree.Kind> nodesToVisit() {
/**
* Tree.Kind.METHOD方法节点
* Tree.Kind.BLOCK方法的代码块节点
* Tree.Kind.METHOD_INVOCATION 方法的调用节点
*/
return Collections.singletonList(Tree.Kind.METHOD);
}
@Override
public void visitNode(Tree tree) {
MethodTree blockTree = (MethodTree) tree;
MethodeBodyVisitor bodyVisitor = new MethodeBodyVisitor(this);
blockTree.accept(bodyVisitor);
}
static class MethodeBodyVisitor extends BaseTreeVisitor {
private final InputSQLVerifyChecker checker;
private List lists = new ArrayList<String>();
MethodeBodyVisitor(InputSQLVerifyChecker checker){
this.checker = checker;
}
@Override
public void visitIfStatement(IfStatementTree tree) {
ExpressionTree condition = tree.condition();
if(condition instanceof MethodInvocationTree){
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) condition;
ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if(expressionTree instanceof MemberSelectExpressionTreeImpl){
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
//将if判断中的参数存入集合中
lists.add(memberSelectExpressionTree.expression().toString());
}
}
}
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect();
if(expressionTree instanceof MemberSelectExpressionTreeImpl){
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) 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语句前应对其进行验证");
}
}
}
}
}
}
}
}
}

@ -0,0 +1,9 @@
<p>使用sql语句前应对其进行验证</p>
<h2>在程序中输入SQL语句,应在拼接SQL语句前对输入字符串数据进行验证,确保输入字符串数据不包含SQL语句的关键字符或仅包含允许的关键字符;在B/S系统中,在前端执行SQL命令检查校验</h2>
<pre>
</pre>
<h2>合规解决方案</h2>
<pre>
</pre>

@ -0,0 +1,13 @@
{
"title": "使用sql语句前应对其进行验证",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"28suo"
],
"defaultSeverity": "Minor"
}

@ -0,0 +1,37 @@
public class InputSQLVerifyRile {
private static final String DB_URL = "jdbc:mysql://localhost:3306/mydatabase";
private static final String USER = "username";
private static final String PASS = "password";
public void executeQuery(String userInput) {
try {
// 获取数据库连接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 假设我们有一个用户ID字段,我们需要根据用户输入查找记录
String sql = "SELECT * FROM users WHERE user_id = ?";
// if(sql.indexOf("a")){
//
// }
// 创建预编译的Statement(PreparedStatement),用问号作为占位符代替实际值
PreparedStatement pstmt = conn.prepareStatement(sql);// Noncompliant {{使用sql语句前应对其进行验证}}
// 验证用户输入是否符合整数格式(这里仅作简单示例)
if (userInput.matches("\\d+")) {
int userId = Integer.parseInt(userInput);
pstmt.setInt(1, userId);
// 执行查询
ResultSet rs = pstmt.executeQuery();
// 处理结果集...
} else {
System.out.println("Invalid input. User ID must be a number.");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,32 @@
/*
* 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 InputSQLVerifyCheckerTest
*
* @author RenFengJiang
* @date 2024/1/14
*/
public class InputSQLVerifyCheckerTest {
@Test
void detected() {
InputSQLVerifyChecker rule = new InputSQLVerifyChecker();
CheckVerifier.newVerifier()
.onFile("src/test/files/InputSQLVerifyRule.java")
.withCheck(rule)
.withClassPath(FilesUtils.getClassPath("target/test-jars"))
.verifyIssues();
}
}
Loading…
Cancel
Save