添加文件上传检查代码

wuhaoyang
DESKTOP-CQC5JJO\Administrator 11 months ago
parent 34d97c1d39
commit f4cec846db
  1. 4
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java
  2. 173
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UploadFileVerifyChecker.java
  3. 9
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/UploadFileVerifyChecker.html
  4. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/UploadFileVerifyChecker.json
  5. 31
      sonar-keyware-plugins-java/src/test/files/UploadFileVerifyRule.java
  6. 37
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/UploadFileVerifyCheckerTest.java

@ -8,6 +8,7 @@ package com.keyware.sonar.java.rules;
import com.keyware.sonar.java.rules.checkers.ABCVarNameChecker;
import com.keyware.sonar.java.rules.checkers.AbsolutePathDetectorChecker;
import com.keyware.sonar.java.rules.checkers.UploadFileVerifyChecker;
import org.sonar.plugins.java.api.JavaCheck;
import java.util.ArrayList;
@ -33,7 +34,8 @@ public final class RulesList {
public static List<Class<? extends JavaCheck>> getJavaChecks() {
return Collections.unmodifiableList(Arrays.asList(
ABCVarNameChecker.class,
AbsolutePathDetectorChecker.class
AbsolutePathDetectorChecker.class,
UploadFileVerifyChecker.class
/*SpringControllerRequestMappingEntityRule.class,
AvoidAnnotationRule.class,
AvoidBrandInMethodNamesRule.class,

@ -0,0 +1,173 @@
/*
* 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.visitors.SubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import java.util.Collections;
import java.util.List;
/**
* TODO 上传文件检查规则
*
* @author RenFengJiang
* @date 2024/1/8
*/
@Rule(key = "UploadFileVerify")
public class UploadFileVerifyChecker extends SubscriptionVisitor {
// 文件全名字
private String fileName = "";
// 文件后缀名
private String fileType = "";
// 是否进行if判断
private boolean nodeOne = true;
// 文件大小
private String sizeName = "";
// 判断权限
private boolean privType = true;
@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 node = (MethodTree) tree;
List<VariableTree> parameters = node.parameters();
// 盘带是否是文件上传类
boolean boo = parameters.stream().anyMatch(type -> "MultipartFile".equals(type.type().toString()));
if(boo){
// 获取文件名称类型判断是否配置文件权限
new InteriorInvoIf().check(tree);
if(fileType != ""){
// 判断是否对文件后缀进行限制
new NodeIf(fileType).check(tree);
}else if(fileName != ""){
// 判断是否对文件后缀进行限制
new NodeIf(fileName).check(tree);
}
// 判断是否获取文件名称
if(nodeOne){
// 没有抛出
context.reportIssue(this, node.simpleName(), "没对上传文件进行判断等操作");
}else {
// 有的话设置位true后续还要用
nodeOne = true;
}
if(sizeName != ""){
// 判断是否对文件大小进行限制
new NodeIf(sizeName).check(tree);
}
// 根据是返回结果进行判断是否抛出异常
if(nodeOne){
context.reportIssue(this, node.simpleName(), "没对上传文件进行判断等操作");
}
// 判断是否进行权限设置
if(privType){
context.reportIssue(this, node.simpleName(), "没对上传文件进行判断等操作");
}
}
}
// 內部文件名称类型获取类
private class InteriorInvoIf extends SubscriptionVisitor{
@Override
public List<Tree.Kind> nodesToVisit() {
return Collections.singletonList(Tree.Kind.METHOD_INVOCATION);
}
@Override
public void visitNode(Tree tree){
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
// 获取到方法调用的参数
ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if(expressionTree instanceof MemberSelectExpressionTree){
MemberSelectExpressionTree expressionTree1 = (MemberSelectExpressionTree) expressionTree;
// 对调用方法进行判断
if("getOriginalFilename".equals(expressionTree1.identifier().toString())){
Tree parent = expressionTree1.parent();
if(parent instanceof MethodInvocationTree){
MethodInvocationTree memberSelectExpressionTree = (MethodInvocationTree) parent;
Tree parent1 = memberSelectExpressionTree.parent();
if(parent1 instanceof VariableTree){
VariableTree variableTree = (VariableTree) parent1;
fileName = variableTree.simpleName().toString();
}
}
}else if("extName".equals(expressionTree1.identifier().toString())){
Tree parent = expressionTree1.parent();
if(parent instanceof MethodInvocationTree){
MethodInvocationTree memberSelectExpressionTree = (MethodInvocationTree) parent;
Tree parent1 = memberSelectExpressionTree.parent();
if(parent1 instanceof VariableTree){
VariableTree variableTree = (VariableTree) parent1;
fileType = variableTree.simpleName().toString();
}
}
}else if("getSize".equals(expressionTree1.identifier().toString())){
Tree parent = expressionTree1.parent();
if(parent instanceof MethodInvocationTree){
MethodInvocationTree memberSelectExpressionTree = (MethodInvocationTree) parent;
Tree parent1 = memberSelectExpressionTree.parent();
if(parent1 instanceof VariableTree){
VariableTree variableTree = (VariableTree) parent1;
sizeName = variableTree.simpleName().toString();
}
}
}else if("setExecutable".equals(expressionTree1.identifier().toString()) || "setReadable".equals(expressionTree1.identifier().toString()) || "setWritable".equals(expressionTree1.identifier().toString())){
privType = false;
}
}
}
public void check(Tree tree){
this.scanTree(tree);
}
}
public class NodeIf extends SubscriptionVisitor{
private String name;
@Override
public List<Tree.Kind> nodesToVisit() {
return Collections.singletonList(Tree.Kind.IF_STATEMENT);
}
public NodeIf(String name) {
this.name = name;
}
public void check(Tree tree){
this.scanTree(tree);
}
@Override
public void visitNode(Tree tree){
IfStatementTree tree1 = (IfStatementTree) tree;
// 获取到if表达式
ExpressionTree condition = tree1.condition();
if(condition instanceof BinaryExpressionTree){
BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) condition;
// 判断是否进行if判断
if(name.equals(binaryExpressionTree.leftOperand().toString())){
nodeOne = false;
}else if(name.equals(binaryExpressionTree.rightOperand().toString())){
nodeOne = false;
}
}
}
}
}

@ -0,0 +1,9 @@
<p>上传文件检查</p>
<h2>程序设计时,应以“白名单”方式限制允许用户上传的文件的类型(如jpg、png、txt、doc、docx、xls、xlsx、xml等格式)并进行检查,根据业务实际需求,设定上传的文件大小,同时限制文件权限(可读、可写、可执行等)</h2>
<pre>
</pre>
<h2>合规解决方案</h2>
<pre>
</pre>

@ -0,0 +1,13 @@
{
"title": "上传文件检查",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"28suo"
],
"defaultSeverity": "Minor"
}

@ -0,0 +1,31 @@
/**
* @author hj
*/
@Slf4j
@RestController
@RequestMapping("/file")
public class UploadFileVerifyRule {
//文件磁盘路径
@Value("${files.upload.path}")
private String fileUploadPath;
@PostMapping("/upload")
public Result upload(@RequestParam MultipartFile file) throws IOException { // Noncompliant {{没对上传文件进行判断等操作}}
file.setExecutable(true);
file.setReadable(true);
file.setWritable(true);
long size = file.getSize();
if(size > 100){
}
//获取文件原始名称
String originalFilename = file.getOriginalFilename();
String type = FileUtil.extName(originalFilename);
return Result.success("");
}
}

@ -0,0 +1,37 @@
/*
* 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 UploadFileVerifyTest
*
* @author RenFengJiang
* @date 2024/1/8
*/
public class UploadFileVerifyCheckerTest {
@Test
void detected() {
UploadFileVerifyChecker rule = new UploadFileVerifyChecker();
// Verifies that the check will raise the adequate issues with the expected message.
// In the test file, lines which should raise an issue have been commented out
// by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}"
CheckVerifier.newVerifier()
.onFile("src/test/files/UploadFileVerifyRule.java")
.withCheck(rule)
.withClassPath(FilesUtils.getClassPath("target/test-jars"))
.verifyIssues();
}
}
Loading…
Cancel
Save