parent
74b8403567
commit
0087499a7e
@ -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…
Reference in new issue