Merge remote-tracking branch 'origin/master'

wuhaoyang
Guo XIn 10 months ago
commit 05ced611ef
  1. 7
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/ConfigFileSquidSensor.java
  2. 1
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/JavaSecurityDesignWayProfile.java
  3. 4
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/JavaSecurityDesignRulesRepository.java
  4. 109
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/AuthenticationChecker.java
  5. 23
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/ConfigCheck.java
  6. 3
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/ConfigurationFileChecker.java
  7. 96
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionDateChecker.java
  8. 9
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/AuthenticationChecker.html
  9. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/AuthenticationChecker.json
  10. 16
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionDateChecker.html
  11. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/SessionDateChecker.json
  12. 22
      sonar-keyware-plugins-java/src/test/files/AuthenticationChecker.java
  13. 9
      sonar-keyware-plugins-java/src/test/files/sessionDates/application.properties
  14. 4
      sonar-keyware-plugins-java/src/test/files/sessionDates/application.yml
  15. 32
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/AuthenticationCheckerTest.java

@ -6,7 +6,9 @@
*/ */
package com.keyware.sonar.java; package com.keyware.sonar.java;
import com.keyware.sonar.java.rules.checkers.ConfigCheck;
import com.keyware.sonar.java.rules.checkers.ConfigurationFileChecker; import com.keyware.sonar.java.rules.checkers.ConfigurationFileChecker;
import com.keyware.sonar.java.rules.checkers.SessionDateChecker;
import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.FilePredicates;
import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.rule.CheckFactory; import org.sonar.api.batch.rule.CheckFactory;
@ -17,13 +19,14 @@ import org.sonar.api.batch.sensor.SensorDescriptor;
public class ConfigFileSquidSensor implements Sensor { public class ConfigFileSquidSensor implements Sensor {
private final Checks<ConfigurationFileChecker> checks; private final Checks<ConfigCheck> checks;
private SensorContext context; private SensorContext context;
public ConfigFileSquidSensor(CheckFactory checkFactory){ public ConfigFileSquidSensor(CheckFactory checkFactory){
checks = checkFactory.create("config"); checks = checkFactory.create("config");
checks.addAnnotatedChecks(ConfigurationFileChecker.class); checks.addAnnotatedChecks(ConfigurationFileChecker.class);
checks.addAnnotatedChecks(SessionDateChecker.class);
} }
@Override @Override
public void describe(SensorDescriptor descriptor) { public void describe(SensorDescriptor descriptor) {
@ -41,6 +44,8 @@ public class ConfigFileSquidSensor implements Sensor {
check.execute(context, inputFile, checks.ruleKey(check)); check.execute(context, inputFile, checks.ruleKey(check));
}); });
} }
checks.all().forEach(check->check.endOfCheck(context, checks.ruleKey(check)));
} }

@ -33,6 +33,7 @@ public class JavaSecurityDesignWayProfile implements BuiltInQualityProfilesDefin
var cfgWay = context.createBuiltInQualityProfile("配置信息安全性设计规则", ConfigurationFileLanguage.KEY); var cfgWay = context.createBuiltInQualityProfile("配置信息安全性设计规则", ConfigurationFileLanguage.KEY);
cfgWay.activateRule("config", "ConfigurationFileChecker"); cfgWay.activateRule("config", "ConfigurationFileChecker");
cfgWay.activateRule("config", "SessionDateChecker");
cfgWay.done(); cfgWay.done();
} }
} }

@ -7,6 +7,8 @@
package com.keyware.sonar.java.rules; package com.keyware.sonar.java.rules;
import com.keyware.sonar.java.rules.checkers.ConfigurationFileChecker; import com.keyware.sonar.java.rules.checkers.ConfigurationFileChecker;
import com.keyware.sonar.java.rules.checkers.SecurityCookieChecker;
import com.keyware.sonar.java.rules.checkers.SessionDateChecker;
import org.sonar.api.SonarEdition; import org.sonar.api.SonarEdition;
import org.sonar.api.SonarProduct; import org.sonar.api.SonarProduct;
import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeSide;
@ -54,7 +56,7 @@ public class JavaSecurityDesignRulesRepository implements RulesDefinition {
htmlRepo.done(); htmlRepo.done();
RulesDefinition.NewRepository configRepo = context.createRepository("config", "cfg").setName("config"); RulesDefinition.NewRepository configRepo = context.createRepository("config", "cfg").setName("config");
ruleMetadataLoader.addRulesByAnnotatedClass(configRepo, List.of(ConfigurationFileChecker.class)); ruleMetadataLoader.addRulesByAnnotatedClass(configRepo, List.of(ConfigurationFileChecker.class, SessionDateChecker.class));
setTemplates(configRepo); setTemplates(configRepo);
configRepo.done(); configRepo.done();
} }

@ -0,0 +1,109 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.model.DefaultModuleScannerContext;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.ModuleScannerContext;
import org.sonar.plugins.java.api.internal.EndOfAnalysis;
import org.sonar.plugins.java.api.tree.*;
import java.util.*;
/**
* TODO 通过用户名口令数据证书等其他手段对用户身份进行验证
* AuthenticationChecker
*
* @author WuHaoYang
* @date 2024/1/23
*/
@Rule(key = "AuthenticationChecker")
public class AuthenticationChecker extends IssuableSubscriptionVisitor implements EndOfAnalysis {
private static final Set<String> VALID_PATHS = new HashSet<>(Arrays.asList("/login", "/auto","signin"));
private boolean isValidPathFound = false;
@Override
public List<Tree.Kind> nodesToVisit() {
return Collections.singletonList(Tree.Kind.METHOD);
}
@Override
public void visitNode(Tree tree) {
MethodTree methodTree = (MethodTree) tree;
for (AnnotationTree annotation : methodTree.modifiers().annotations()) {
if (isWebAnnotation(annotation)) {
if (checkAnnotationArguments(annotation)) {
isValidPathFound = true;
break;
}
}
}
}
private boolean isWebAnnotation(AnnotationTree annotation) {
TypeTree typeTree = annotation.annotationType();
return "PostMapping".equals(typeTree.toString()) || "RequestMapping".equals(typeTree.toString());
}
private boolean checkAnnotationArguments(AnnotationTree annotation) {
for (ExpressionTree arg : annotation.arguments()) {
if (arg.is(Tree.Kind.ASSIGNMENT)) {
AssignmentExpressionTree aet = (AssignmentExpressionTree) arg;
IdentifierTree it = (IdentifierTree) aet.variable();
if ("value".equals(it.name())) {
if (aet.expression().is(Tree.Kind.NEW_ARRAY)) {
NewArrayTree nat = (NewArrayTree) aet.expression();
for (ExpressionTree et : nat.initializers()) {
LiteralTree lt = (LiteralTree) et;
System.out.println(lt.value().toString());
if (checkUrl(lt.value().toString())) {
return true;
}
}
} else if (aet.expression().is(Tree.Kind.STRING_LITERAL)) {
LiteralTree lt = (LiteralTree) aet.expression();
System.out.println(lt.value().toString());
if (checkUrl(lt.value().toString())) {
return true;
}
}
}
} else if (arg.is(Tree.Kind.STRING_LITERAL)) {
LiteralTree lt = (LiteralTree) arg;
System.out.println(lt.value().toString());
if (checkUrl(lt.value().toString())) {
return true;
}
}
}
return false;
}
private boolean checkUrl(String url) {
for (String validPath : VALID_PATHS) {
if (url.endsWith(validPath) || url.contains(validPath)) {
return true;
}
}
return false;
}
@Override
public void endOfAnalysis(ModuleScannerContext context) {
var defaultContext = (DefaultModuleScannerContext) context;
if (!isValidPathFound) {
System.out.println("应通过用户名口令、数据证书等其他手段对用户身份进行验证");
defaultContext.addIssueOnProject(this, "应通过用户名口令、数据证书等其他手段对用户身份进行验证");
}
}
}

@ -0,0 +1,23 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.rules.checkers;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.rule.RuleKey;
/**
* TODO ConfigCheck
*
* @author RenFengJiang
* @date 2024/1/23
*/
public interface ConfigCheck {
default void execute(SensorContext context, InputFile inputFile, RuleKey ruleKey){}
default void endOfCheck(SensorContext context, RuleKey ruleKey){}
}

@ -35,9 +35,10 @@ import java.util.Scanner;
* @date 2024/1/22 * @date 2024/1/22
*/ */
@Rule(key = "ConfigurationFileChecker") @Rule(key = "ConfigurationFileChecker")
public class ConfigurationFileChecker { public class ConfigurationFileChecker implements ConfigCheck {
@Override
public void execute(SensorContext context, InputFile inputFile, RuleKey ruleKey){ public void execute(SensorContext context, InputFile inputFile, RuleKey ruleKey){
//文件名称 //文件名称
String filename = inputFile.filename(); String filename = inputFile.filename();

@ -0,0 +1,96 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.rules.checkers;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.rule.RuleKey;
import org.sonar.check.Rule;
import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;
import java.util.Scanner;
/**
* TODO SessionDateChecker
*
* @author RenFengJiang
* @date 2024/1/22
*/
@Rule(key = "SessionDateChecker")
public class SessionDateChecker implements ConfigCheck {
private boolean boo = true;
public void execute(SensorContext context, InputFile inputFile, RuleKey ruleKey){
if(boo){
//文件名称
String filename = inputFile.filename();
//校验文件后缀
if (filename.endsWith(".properties")) {
try {
File file = new File(inputFile.absolutePath());
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.contains("server.servlet.session.timeout")) {
boo = false;
break;
}
}
}
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
return; // 文件未找到时立即返回
}
}
if (filename.endsWith(".yml")){
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
File absoluteFile = file1.getAbsoluteFile();
// 构建目录路径
Yaml yaml = new Yaml();
try (FileInputStream fis = new FileInputStream(file1)) {
Map<String, Object> obj = yaml.load(fis);
if (obj != null){
String sessionTimeout = searchForSessionTimeout(obj, "server", "servlet", "session", "timeout");
if (sessionTimeout != null) {
boo = false;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private String searchForSessionTimeout(Map<String, Object> map, String... keys) {
Map<String, Object> currentLevel = map;
for (int i = 0; i < keys.length - 1; ++i) {
Object nextLevel = currentLevel.get(keys[i]);
if (nextLevel instanceof Map) {
currentLevel = (Map<String, Object>) nextLevel;
} else {
return null;
}
}
return currentLevel.get(keys[keys.length - 1]).toString();
}
@Override
public void endOfCheck(SensorContext context, RuleKey ruleKey) {
if(boo){
var issue = context.newIssue();
issue.at(issue.newLocation().on(context.project()).message("设置会话过期的日期")).forRule(ruleKey).save();
}
}
}

@ -0,0 +1,9 @@
<p>通过用户名口令、数据证书等其他手段对用户身份进行验证</p>
<h2>通过用户名口令、数据证书等其他手段对用户身份进行验证</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,16 @@
<!--
~ Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
~ 项目名称:信息安全性设计准则检查插件
~ 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件
~ 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
-->
<p>设置会话过期的日期</p>
<h2>设置会话过期的日期</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,22 @@
@Controller
public class AuthController {
@PostMapping("/account/aa")
public String login() {
return "login";
}
@PostMapping(value ={"/path/bb", "/path/www", "/path/eee"})
public String signin() {
return "login";
}
@RequestMapping("/myapp/cc")
public String auth() {
return "login";
}
}

@ -0,0 +1,9 @@
#
# Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
# 项目名称:信息安全性设计准则检查插件
# 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件
# 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
#
# 设置会话超时时间为30分钟
server.servlet.session.timeout=30m

@ -0,0 +1,32 @@
/*
* 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;
/**
* 通过用户名口令数据证书等其他手段对用户身份进行验证 单元测试类
*
* @author WuHaoYang
* @date 2024/1/23
*/
public class AuthenticationCheckerTest {
@Test
void detected() {
CheckVerifier.newVerifier()
.onFiles("src/test/files/AuthenticationChecker.java")
.withCheck(new AuthenticationChecker())
.withClassPath(FilesUtils.getClassPath("target/test-jars"))
.verifyIssueOnProject("应通过用户名口令、数据证书等其他手段对用户身份进行验证");
}
}
Loading…
Cancel
Save