武浩阳 工作暂存

wuhaoyang
wuhaoyang 10 months ago
parent b4147782d6
commit e76715936e
  1. 268
      sonar-keyware-plugins-ConfigurationDetection/pom.xml
  2. 11
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/ConfigFileSquidSensor.java
  3. 2
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/ConfigurationFileLanguage.java
  4. 37
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/ConfigurationSecurityDesignRulesPlugin.java
  5. 29
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/ConfigurationSecurityDesignWayProfile.java
  6. 10
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/package-info.java
  7. 55
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/rules/ConfigurationSecurityDesignRulesRepository.java
  8. 23
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/rules/checkers/ConfigCheck.java
  9. 250
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/rules/checkers/ConfigurationFileChecker.java
  10. 96
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/rules/checkers/SessionDateChecker.java
  11. 13
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/rules/package-info.java
  12. 4
      sonar-keyware-plugins-ConfigurationDetection/src/main/resources/license-header.txt
  13. 9
      sonar-keyware-plugins-ConfigurationDetection/src/main/resources/org/sonar/l10n/java/rules/java/ConfigurationFileChecker.html
  14. 13
      sonar-keyware-plugins-ConfigurationDetection/src/main/resources/org/sonar/l10n/java/rules/java/ConfigurationFileChecker.json
  15. 16
      sonar-keyware-plugins-ConfigurationDetection/src/main/resources/org/sonar/l10n/java/rules/java/SessionDateChecker.html
  16. 13
      sonar-keyware-plugins-ConfigurationDetection/src/main/resources/org/sonar/l10n/java/rules/java/SessionDateChecker.json
  17. 2
      sonar-keyware-plugins-ConfigurationDetection/src/test/files/configFile/ConfigurationFileChecker.conf
  18. 3
      sonar-keyware-plugins-ConfigurationDetection/src/test/files/configFile/ConfigurationFileChecker.ini
  19. 5
      sonar-keyware-plugins-ConfigurationDetection/src/test/files/configFile/ConfigurationFileChecker.json
  20. 2
      sonar-keyware-plugins-ConfigurationDetection/src/test/files/configFile/ConfigurationFileChecker.properties
  21. 7
      sonar-keyware-plugins-ConfigurationDetection/src/test/files/configFile/ConfigurationFileChecker.xml
  22. 3
      sonar-keyware-plugins-ConfigurationDetection/src/test/files/configFile/ConfigurationFileChecker.yml
  23. 9
      sonar-keyware-plugins-ConfigurationDetection/src/test/files/sessionDates/application.properties
  24. 4
      sonar-keyware-plugins-ConfigurationDetection/src/test/files/sessionDates/application.yml
  25. 70
      sonar-keyware-plugins-ConfigurationDetection/src/test/java/com/keyware/sonar/java/ConfigurationSecurityDesignRulesPluginTest.java
  26. 34
      sonar-keyware-plugins-ConfigurationDetection/src/test/java/com/keyware/sonar/java/rules/ConfigurationSecurityDesignRulesRepositoryTest.java
  27. 75
      sonar-keyware-plugins-ConfigurationDetection/src/test/java/com/keyware/sonar/java/utils/FilesUtils.java
  28. 113
      sonar-keyware-plugins-ConfigurationDetection/src/test/java/com/keyware/sonar/java/utils/HtmlCheckMessagesVerifier.java
  29. 43
      sonar-keyware-plugins-ConfigurationDetection/src/test/java/com/keyware/sonar/java/utils/HtmlCheckMessagesVerifierRule.java
  30. 66
      sonar-keyware-plugins-ConfigurationDetection/src/test/java/com/keyware/sonar/java/utils/HtmlTestHelper.java
  31. 4
      sonar-keyware-plugins-cxx/pom.xml
  32. 30
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/ConfigurationFileLanguage.java
  33. 11
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxPlugin.java
  34. 11
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxSonarWayProfile.java
  35. 6
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxSquidSensor.java
  36. 47
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/FlagLineSensor.java
  37. 37
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/LogLanguage.java
  38. 31
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/LogRuleRepository.java
  39. 18
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/SecurityDesignRuleRepository.java
  40. 32
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/SecurityDesignWayProfile.java
  41. 265
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ConfigurationFileChecker.java
  42. 16
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FlagLineRule.java
  43. 78
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SqlVarNameChecker.java
  44. 6
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/CxxRuleRepositoryTest.java
  45. 72
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/ConfigurationFileCheckerTest.java
  46. 14
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/JavaSecurityDesignRulesPlugin.java
  47. 8
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/JavaSecurityDesignWayProfile.java
  48. 10
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/JavaSecurityDesignRulesRepository.java
  49. 276
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/ConfigurationFileChecker.java
  50. 9
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/JavaSecurityDesignRulesPluginTest.java

@ -0,0 +1,268 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.keyware.sonar</groupId>
<artifactId>sonar-keyware</artifactId>
<version>1.0</version>
</parent>
<name>配置文件信息安全性设计准则</name>
<artifactId>sonar-keyware-plugins-configurationDetection</artifactId>
<packaging>sonar-plugin</packaging>
<version>1.0</version>
<description>用于检查配置文件信息的安全性设计准则的Sonarqube插件</description>
<properties>
<sonar.sources>src/main/java,src/main/resources</sonar.sources>
</properties>
<dependencies>
<dependency>
<groupId>org.sonarsource.api.plugin</groupId>
<artifactId>sonar-plugin-api</artifactId>
<version>9.9.0.229</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.html</groupId>
<artifactId>sonar-html-plugin</artifactId>
<version>${sonar.html.version}</version>
<!--<type>sonar-plugin</type>-->
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.analyzer-commons</groupId>
<artifactId>sonar-analyzer-commons</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>test</scope>
</dependency>
<!-- unit tests -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-migrationsupport</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.28</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.12.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.16.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
<artifactId>sonar-packaging-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<pluginKey>keywareConfigurationDetectionPlugin</pluginKey>
<pluginName>配置文件信息设计准则</pluginName>
<pluginClass>com.keyware.sonar.Configuration.ConfigurationSecurityDesignRulesPlugin</pluginClass>
<sonarLintSupported>true</sonarLintSupported>
<skipDependenciesPackaging>true</skipDependenciesPackaging>
<sonarQubeMinVersion>8.9</sonarQubeMinVersion>
<jreMinVersion>11</jreMinVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${version.jacoco.plugin}</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- only required to run UT - these are UT dependencies -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>test-compile</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.3.RELEASE</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.3.RELEASE</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.3.RELEASE</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<type>jar</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/test-jars</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<configuration>
<header>${project.basedir}/src/main/resources/license-header.txt</header>
<!--排除文件-->
<excludes>
<exclude>**/*.properties</exclude>
<exclude>*.sh</exclude>
<exclude>*.yml</exclude>
<exclude>.editorconfig</exclude>
<exclude>.gitignore</exclude>
<exclude>**/*.md</exclude>
<exclude>**/*.xml</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -4,11 +4,11 @@
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java;
package com.keyware.sonar.Configuration;
import com.keyware.sonar.java.rules.checkers.ConfigCheck;
import com.keyware.sonar.java.rules.checkers.ConfigurationFileChecker;
import com.keyware.sonar.java.rules.checkers.SessionDateChecker;
import com.keyware.sonar.Configuration.rules.checkers.SessionDateChecker;
import com.keyware.sonar.Configuration.rules.checkers.ConfigCheck;
import com.keyware.sonar.Configuration.rules.checkers.ConfigurationFileChecker;
import org.sonar.api.batch.fs.FilePredicates;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.rule.CheckFactory;
@ -44,8 +44,7 @@ public class ConfigFileSquidSensor implements Sensor {
check.execute(context, inputFile, checks.ruleKey(check));
});
}
checks.all().forEach(check->check.endOfCheck(context, checks.ruleKey(check)));
checks.all().forEach(check -> check.endOfCheck(context, checks.ruleKey(check)));
}

@ -4,7 +4,7 @@
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java;
package com.keyware.sonar.Configuration;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.PropertyDefinition;

@ -0,0 +1,37 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.Configuration;
import com.keyware.sonar.Configuration.rules.ConfigurationSecurityDesignRulesRepository;
import org.sonar.api.Plugin;
/**
* 安全性设计准则插件
*
* @author GuoXin
* @date 2024/1/6
*/
public class ConfigurationSecurityDesignRulesPlugin implements Plugin {
@Override
public void define(Context context) {
// 服务器扩展 - >对象在服务器启动期间实例化
context.addExtension(ConfigurationSecurityDesignRulesRepository.class);
// 服务器扩展 - >对象在服务器启动期间实例化
context.addExtension(ConfigurationSecurityDesignWayProfile.class);
context.addExtension(ConfigurationFileLanguage.class);
context.addExtension(ConfigFileSquidSensor.class);
context.addExtensions(ConfigurationFileLanguage.getProperties());
}
}

@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.Configuration;
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
import org.sonarsource.api.sonarlint.SonarLintSide;
/**
* 定义配置信息安全性质量配置
*
* @author GuoXin
* @date 2024/1/11
*/
@SonarLintSide
public class ConfigurationSecurityDesignWayProfile implements BuiltInQualityProfilesDefinition {
@Override
public void define(Context context) {
var cfgWay = context.createBuiltInQualityProfile("配置信息安全性设计规则", ConfigurationFileLanguage.KEY);
cfgWay.activateRule("config", "ConfigurationFileChecker");
cfgWay.activateRule("config", "SessionDateChecker");
cfgWay.done();
}
}

@ -4,14 +4,10 @@
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx.rules;
/**
* C++ 安全设计准则检查规则属性
* TODO package-info
*
* @author GuoXin
* @date 2024/1/18
* @date 2024/1/12
*/
public class SecurityDesignRuleProperties {
}
package com.keyware.sonar.Configuration;

@ -0,0 +1,55 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.Configuration.rules;
import com.keyware.sonar.Configuration.rules.checkers.SessionDateChecker;
import com.keyware.sonar.Configuration.rules.checkers.ConfigurationFileChecker;
import org.sonar.api.SonarRuntime;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonarsource.analyzer.commons.RuleMetadataLoader;
import java.util.*;
/**
* 用于定义出现在规则页面中规则的元数据
*
* @author GuoXin
* @date 2024/1/6
*/
public class ConfigurationSecurityDesignRulesRepository implements RulesDefinition {
// 不要修改这个值,因为路径在 CheckVerifier 中是硬编码的
private static final String RESOURCE_BASE_PATH = "org/sonar/l10n/java/rules/java";
// 添加需要视为模板规则的规则的规则键
private static final Set<String> RULE_TEMPLATES_KEY = Collections.emptySet();
private final SonarRuntime runtime;
public ConfigurationSecurityDesignRulesRepository(SonarRuntime runtime) {
this.runtime = runtime;
}
@Override
public void define(RulesDefinition.Context context) {
RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, runtime);
RulesDefinition.NewRepository configRepo = context.createRepository("config", "cfg").setName("config");
ruleMetadataLoader.addRulesByAnnotatedClass(configRepo, List.of(ConfigurationFileChecker.class, SessionDateChecker.class));
setTemplates(configRepo);
configRepo.done();
}
private static void setTemplates(RulesDefinition.NewRepository repository) {
RULE_TEMPLATES_KEY.stream()
.map(repository::rule)
.filter(Objects::nonNull)
.forEach(rule -> rule.setTemplate(true));
}
}

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

@ -0,0 +1,250 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.Configuration.rules.checkers;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.check.Rule;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.yaml.snakeyaml.Yaml;
import javax.xml.parsers.*;
import java.io.*;
import java.util.Map;
import java.util.Scanner;
/**
* 通过用户名口令数据证书等其他手段对用户身份进行验证
*
* @author WuHaoYang
* @date 2024/1/22
*/
@Rule(key = "ConfigurationFileChecker")
public class ConfigurationFileChecker implements ConfigCheck{
public void execute(SensorContext context, InputFile inputFile, RuleKey ruleKey){
//文件名称
String filename = inputFile.filename();
System.out.println("[ConfigurationFileChecker]>>>>>" + filename);
//校验文件后缀
if (filename.endsWith(".properties")) {
try {
File file = new File(inputFile.absolutePath());
try (Scanner scanner = new Scanner(file)) {
int lineNum = 1;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] keyValue = line.split("="); // 分割行的内容
// 检查键是否为 "password" 且其对应的值不为空
if (keyValue.length == 2 && keyValue[0].trim().equals("password")
&& !keyValue[1].trim().isEmpty()) {
NewIssue newIssue = context.newIssue();
newIssue.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
}
lineNum++;
}
}
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
}
}
if (filename.endsWith(".ini")) {
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
try (BufferedReader br = new BufferedReader(new FileReader(file1))) {
String line;
int lineNum = 1;
while ((line = br.readLine()) != null) {
if (line.trim().startsWith("password")) {
NewIssue newIssue = context.newIssue();
newIssue.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
break;
}
lineNum++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (filename.endsWith(".conf")) {
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
int lineNum = 0; // 初始化行数
try {
BufferedReader br = new BufferedReader(new FileReader(file1));
String line;
while ((line = br.readLine()) != null) {
lineNum++; // 递增行数
String[] keyValue = line.split("="); // 分割行的内容
// 进行基本有效性检查 && keyValue[0]可能包含前导空格, keyValue[1]可能包含尾随空格
if (keyValue.length == 2 && keyValue[0].trim().equals("password")) {
// 如果键是 "password", 输出其值
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
}
}
br.close();
} catch(FileNotFoundException ex) {
ex.printStackTrace();
} catch(IOException ex) {
ex.printStackTrace();
}
}
if (filename.endsWith(".xml") && !filename.equals("pom.xml")){
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
File absoluteFile = file1.getAbsoluteFile();
File xmlFile = absoluteFile;
processXML(xmlFile);
}
if (filename.endsWith(".json")) {
try {
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
JsonFactory f = new MappingJsonFactory();
JsonParser jp = f.createParser(file1);
JsonToken current;
current = jp.nextToken();
if (current != JsonToken.START_OBJECT) {
return;
}
while (jp.nextToken() != JsonToken.END_OBJECT) {
String fieldName = jp.getCurrentName();
current = jp.nextToken();
if ("password".equals(fieldName)) {
int lineNum = jp.getCurrentLocation().getLineNr();
String passwordValue = jp.getText();
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (filename.endsWith(".yml")){
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
Yaml yaml = new Yaml();
try (FileInputStream fis = new FileInputStream(file1)) {
Map<String, Object> obj = yaml.load(fis);
if (obj != null) {
String password = searchPassword(obj, 1);
if (password != null) {
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static String searchPassword(Map<String, Object> map, int lineNum) {
for (String key : map.keySet()) {
if ("password".equals(key) && map.get(key) instanceof String) {
return (String) map.get(key);
} else if (map.get(key) instanceof Map) {
lineNum++;
String password = searchPassword((Map<String, Object>) map.get(key), lineNum);
if (password != null) {
return password;
}
}
}
return null;
}
public static int getLineNumber(Node node) {
Document document = node.getOwnerDocument();
document.getDocumentElement().normalize();
String xmlContent = document.getDocumentElement().getTextContent();
String[] lines = xmlContent.split("\n");
for(int i = 0; i < lines.length; i++) {
if(lines[i].contains(node.getTextContent())) {
return i+2;
}
}
return -1;
}
public static void processXML(File xmlFile) {
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("password");
for (int i = 0; i < nList.getLength(); i++) {
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
int lineNumber = getLineNumber(nNode);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,96 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.Configuration.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;
/**
* 设置会话过期的日期
*
* @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,13 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
/**
* TODO package-info
*
* @author GuoXin
* @date 2024/1/12
*/
package com.keyware.sonar.Configuration.rules;

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

@ -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,3 @@
[UserCredentials]
username = exampleUser
password = iniPassword

@ -0,0 +1,5 @@
{
"username": "john_doe",
"password": "jsonPassword",
"email": "john.doe@example.com"
}

@ -0,0 +1,2 @@
# ConfigurationFileChecker.properties
password=propertiesPassword

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<user>
<username>exampleUser</username>
<password>xmlPassword</password>
</user>

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

@ -0,0 +1,70 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java;
import com.keyware.sonar.Configuration.ConfigurationSecurityDesignRulesPlugin;
import org.junit.jupiter.api.Test;
import org.sonar.api.*;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.utils.Version;
import static org.assertj.core.api.Assertions.assertThat;
/**
* TODO JavaSecurityDesignRulesPluginTest
*
* @author GuoXin
* @date 2024/1/6
*/
public class ConfigurationSecurityDesignRulesPluginTest {
@Test
void testName() {
Plugin.Context context = new Plugin.Context(new MockedSonarRuntime());
new ConfigurationSecurityDesignRulesPlugin().define(context);
assertThat(context.getExtensions())
.extracting((ext) -> {
var type = ext.getClass().getSimpleName();
if("Class".equals(type)){
return ((Class) ext).getSimpleName();
}else if("PropertyDefinition".equals(type)){
return ((PropertyDefinition) ext).name();
}
return ext.getClass().getSimpleName();
})
.containsExactlyInAnyOrder(
"ConfigurationSecurityDesignRulesRepository",
"ConfigurationSecurityDesignWayProfile",
"ConfigurationFileLanguage",
"ConfigFileSquidSensor",
"File Suffixes");
}
public static class MockedSonarRuntime implements SonarRuntime {
@Override
public Version getApiVersion() {
return Version.create(9, 9);
}
@Override
public SonarProduct getProduct() {
return SonarProduct.SONARQUBE;
}
@Override
public SonarQubeSide getSonarQubeSide() {
return SonarQubeSide.SCANNER;
}
@Override
public SonarEdition getEdition() {
return SonarEdition.COMMUNITY;
}
}
}

@ -0,0 +1,34 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.rules;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* TODO JavaSecurityDesignRulesRepositoryTest
*
* @author GuoXin
* @date 2024/1/6
*/
public class ConfigurationSecurityDesignRulesRepositoryTest {
@Test
void test() {
// JavaSecurityDesignRulesRepository rulesDefinition = new JavaSecurityDesignRulesRepository(new JavaSecurityDesignRulesRepository.MockedSonarRuntime());
// RulesDefinition.Context context = new RulesDefinition.Context();
// rulesDefinition.define(context);
// RulesDefinition.Repository repository = context.repository(JavaSecurityDesignRulesRepository.REPOSITORY_KEY);
//
// assertThat(repository.name()).isEqualTo(JavaSecurityDesignRulesRepository.REPOSITORY_NAME);
// assertThat(repository.language()).isEqualTo("java");
// assertThat(repository.rules()).hasSize(RulesList.getJavaRules().size());
// assertThat(repository.rules().stream().filter(RulesDefinition.Rule::template)).isEmpty();
}
}

@ -0,0 +1,75 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.utils;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Duplicates org.sonar.java.checks.verifier.FilesUtils to locate test jars within the custom-rules plugin
*/
public class FilesUtils {
private FilesUtils() {
}
/**
* Default location of the jars/zips to be taken into account when performing the analysis.
*/
private static final String DEFAULT_TEST_JARS_DIRECTORY = "target/test-jars";
public static List<File> getClassPath(String jarsDirectory) {
List<File> classpath = new LinkedList<>();
Path testJars = Paths.get(jarsDirectory);
if (testJars.toFile().exists()) {
classpath = getFilesRecursively(testJars, "jar", "zip");
} else if (!DEFAULT_TEST_JARS_DIRECTORY.equals(jarsDirectory)) {
throw new AssertionError("The directory to be used to extend class path does not exists ("
+ testJars.toAbsolutePath()
+ ").");
}
classpath.add(new File("target/test-classes"));
return classpath;
}
private static List<File> getFilesRecursively(Path root, String... extensions) {
final List<File> files = new ArrayList<>();
FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) {
for (String extension : extensions) {
if (filePath.toString().endsWith("."
+ extension)) {
files.add(filePath.toFile());
break;
}
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
};
try {
Files.walkFileTree(root, visitor);
} catch (IOException e) {
// we already ignore errors in the visitor
}
return files;
}
}

@ -0,0 +1,113 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.utils;
import org.sonar.plugins.html.checks.HtmlIssue;
import org.sonar.plugins.html.checks.PreciseHtmlIssue;
import javax.annotation.Nullable;
import java.util.*;
/**
* Html检查消息验证器
*
* @author GuoXin
* @date 2024/1/20
*/
public final class HtmlCheckMessagesVerifier {
public static HtmlCheckMessagesVerifier verify(Collection<HtmlIssue> messages) {
return new HtmlCheckMessagesVerifier(messages);
}
private final Iterator<HtmlIssue> iterator;
private HtmlIssue current;
private static final Comparator<HtmlIssue> ORDERING = (left, right) -> {
if (Objects.equals(left.line(), right.line())) {
return left.message().compareTo(right.message());
} else if (left.line() == null) {
return -1;
} else if (right.line() == null) {
return 1;
} else {
return left.line().compareTo(right.line());
}
};
private HtmlCheckMessagesVerifier(Collection<HtmlIssue> messages) {
ArrayList<HtmlIssue> messagesList = new ArrayList<>(messages);
messagesList.sort(ORDERING);
iterator = messagesList.iterator();
}
public HtmlCheckMessagesVerifier next() {
if (!iterator.hasNext()) {
throw new AssertionError("\nExpected violation");
}
current = iterator.next();
return this;
}
public void noMore() {
if (iterator.hasNext()) {
HtmlIssue next = iterator.next();
throw new AssertionError("\nNo more violations expected\ngot: at line " + next.line());
}
}
private void checkStateOfCurrent() {
if (current == null) {
throw new IllegalStateException("Prior to this method you should call next()");
}
}
public HtmlCheckMessagesVerifier atLine(@Nullable Integer expectedLine) {
checkStateOfCurrent();
if (!Objects.equals(expectedLine, current.line())) {
throw new AssertionError("\nExpected: " + expectedLine + "\ngot: " + current.line());
}
return this;
}
public HtmlCheckMessagesVerifier atLocation(int startLine, int startColumn, int endLine, int endColumn) {
checkStateOfCurrent();
PreciseHtmlIssue preciseHtmlIssue = (PreciseHtmlIssue) current;
if (!Objects.equals(startLine, current.line())) {
throw new AssertionError("\nExpected: " + startLine + "\ngot: " + current.line());
}
if (!Objects.equals(startColumn, preciseHtmlIssue.startColumn())) {
throw new AssertionError("\nExpected: " + startColumn + "\ngot: " + preciseHtmlIssue.startColumn());
}
if (!Objects.equals(endLine, preciseHtmlIssue.endLine())) {
throw new AssertionError("\nExpected: " + endLine + "\ngot: " + preciseHtmlIssue.endLine());
}
if (!Objects.equals(endColumn, preciseHtmlIssue.endColumn())) {
throw new AssertionError("\nExpected: " + endColumn + "\ngot: " + preciseHtmlIssue.endColumn());
}
return this;
}
public HtmlCheckMessagesVerifier withMessage(String expectedMessage) {
checkStateOfCurrent();
String actual = current.message();
if (!actual.equals(expectedMessage)) {
throw new AssertionError("\nExpected: \"" + expectedMessage + "\"\ngot: \"" + actual + "\"");
}
return this;
}
public HtmlCheckMessagesVerifier withCost(@Nullable Double expectedCost) {
checkStateOfCurrent();
if (!Objects.equals(expectedCost, current.cost())) {
throw new AssertionError("\nExpected: " + expectedCost + "\ngot: " + current.cost());
}
return this;
}
}

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.utils;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.sonar.plugins.html.checks.HtmlIssue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Html规则校验
*
* @author GuoXin
* @date 2024/1/20
*/
public class HtmlCheckMessagesVerifierRule implements AfterEachCallback {
private final List<HtmlCheckMessagesVerifier> verifiers = new ArrayList<>();
public HtmlCheckMessagesVerifier verify(Collection<HtmlIssue> messages) {
HtmlCheckMessagesVerifier verifier = HtmlCheckMessagesVerifier.verify(messages);
verifiers.add(verifier);
return verifier;
}
protected void verify() {
for (HtmlCheckMessagesVerifier verifier : verifiers) {
verifier.noMore();
}
}
@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
verify();
}
}

@ -0,0 +1,66 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.utils;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.plugins.html.analyzers.ComplexityVisitor;
import org.sonar.plugins.html.analyzers.PageCountLines;
import org.sonar.plugins.html.api.HtmlConstants;
import org.sonar.plugins.html.lex.PageLexer;
import org.sonar.plugins.html.lex.VueLexer;
import org.sonar.plugins.html.visitor.DefaultNodeVisitor;
import org.sonar.plugins.html.visitor.HtmlAstScanner;
import org.sonar.plugins.html.visitor.HtmlSourceCode;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* Html测试工具类
*
* @author GuoXin
* @date 2024/1/20
*/
public class HtmlTestHelper {
private HtmlTestHelper() {
}
public static HtmlSourceCode scan(File file, DefaultNodeVisitor visitor) {
FileReader fileReader;
try {
fileReader = new FileReader(file);
} catch (FileNotFoundException e) {
throw new IllegalStateException(e);
}
HtmlSourceCode result = new HtmlSourceCode(
new TestInputFileBuilder("key", file.getPath())
.setLanguage(HtmlConstants.LANGUAGE_KEY)
.setType(InputFile.Type.MAIN)
.setModuleBaseDir(new File(".").toPath())
.setCharset(StandardCharsets.UTF_8)
.build()
);
HtmlAstScanner walker = new HtmlAstScanner(List.of(new PageCountLines(), new ComplexityVisitor()));
PageLexer lexer = file.getName().endsWith(".vue") ? new VueLexer() : new PageLexer();
walker.addVisitor(visitor);
walker.scan(
lexer.parse(fileReader),
result
);
return result;
}
}

@ -17,8 +17,8 @@
</parent>-->
<!--<groupId>com.keyware.sonar</groupId>-->
<name>C++ 信息安全性设计准则</name>
<artifactId>sonar-keyware-plugins-cxx</artifactId>
<name>28所 C++ 信息安全性设计准则</name>
<artifactId>sonar-keyware-plugins-cxx-28suo</artifactId>
<version>1.0</version>
<packaging>sonar-plugin</packaging>
<description>用于检查C++源代码的安全性设计准则的Sonarqube插件</description>

@ -1,30 +0,0 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx;
import org.sonar.api.resources.AbstractLanguage;
import java.lang.module.Configuration;
public final class ConfigurationFileLanguage extends AbstractLanguage {
public static final String NAME = "Configuration";
public static final String KEY = "cfg";
private final Configuration config;
public ConfigurationFileLanguage (Configuration config) {
super(KEY, NAME);
this.config = config;
}
@Override
public String[] getFileSuffixes() {
return new String[] {".yml", ".properties", ".ini",".conf" ,".xml" ,".json"};
}
}

@ -1,6 +1,6 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
@ -62,17 +62,21 @@ public final class CxxPlugin implements Plugin {
var l = new ArrayList<Object>();
// plugin elements
l.add(FlagLineSensor.class);
l.add(CxxLanguage.class);
l.add(LogLanguage.class);
l.add(CxxSonarWayProfile.class);
l.add(SecurityDesignWayProfile.class);
l.add(CxxRuleRepository.class);
l.add(LogRuleRepository.class);
l.add(SecurityDesignRuleRepository.class);
// reusable elements
l.addAll(getSensorsImpl());
// properties elements
l.addAll(CxxLanguage.properties());
l.addAll(LogLanguage.properties());
l.addAll(CxxSquidSensor.properties());
l.addAll(CxxCppCheckSensor.properties());
l.addAll(CxxValgrindSensor.properties());
@ -98,8 +102,7 @@ public final class CxxPlugin implements Plugin {
static private List<Object> getSensorsImpl() {
var l = new ArrayList<Object>();
l.add(LogLanguage.class);
l.add(ConfigurationFileLanguage.class);
// l.add(ConfigurationFileLanguage.class);
// utility classes
l.add(CxxUnitTestResultsAggregator.class);

@ -1,6 +1,6 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
@ -8,7 +8,6 @@ package com.keyware.sonar.cxx;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.keyware.sonar.cxx.rules.SecurityDesignRuleRepository;
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
import org.sonar.cxx.checks.CheckList;
import org.sonarsource.api.sonarlint.SonarLintSide;
@ -45,6 +44,14 @@ public class CxxSonarWayProfile implements BuiltInQualityProfilesDefinition {
sonarWay.activateRule(CheckList.REPOSITORY_KEY, key);
});
sonarWay.done();
var sonarWay1 = context.createBuiltInQualityProfile("log", LogLanguage.KEY);
Profile jsonProfile1 = readProfile();
jsonProfile1.ruleKeys.forEach((key) -> {
sonarWay1.activateRule(CheckList.REPOSITORY_KEY, key);
});
sonarWay1.done();
}
static class Profile {

@ -1,6 +1,6 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
@ -287,7 +287,7 @@ public class CxxSquidSensor implements ProjectSensor {
public void describe(SensorDescriptor descriptor) {
descriptor
.name("CXX")
.onlyOnLanguages(CxxLanguage.KEY, LogLanguage.KEY, ConfigurationFileLanguage.KEY)
.onlyOnLanguages(CxxLanguage.KEY, LogLanguage.KEY)
.onlyOnFileType(InputFile.Type.MAIN)
.onlyWhenConfiguration(conf -> !conf.getBoolean(SQUID_DISABLED_KEY).orElse(false));
}
@ -374,7 +374,7 @@ public class CxxSquidSensor implements ProjectSensor {
private Iterable<InputFile> getInputFiles(SensorContext context, CxxSquidConfiguration squidConfig) {
Iterable<InputFile> inputFiles = context.fileSystem().inputFiles(
context.fileSystem().predicates().and(
context.fileSystem().predicates().hasLanguages(CxxLanguage.KEY, LogLanguage.KEY, ConfigurationFileLanguage.KEY),
context.fileSystem().predicates().hasLanguages(CxxLanguage.KEY, LogLanguage.KEY),
context.fileSystem().predicates().hasType(InputFile.Type.MAIN)
)
);

@ -0,0 +1,47 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx;
import com.keyware.sonar.cxx.rules.checkers.FlagLineRule;
import com.keyware.sonar.cxx.rules.checkers.SqlVarNameChecker;
import org.sonar.api.batch.fs.FilePredicates;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.rule.CheckFactory;
import org.sonar.api.batch.rule.Checks;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
public class FlagLineSensor implements Sensor {
private final Checks<FlagLineRule> checks;
public FlagLineSensor(CheckFactory checkFactory) {
checks = checkFactory.create("cxx-security-design-rules");
checks.addAnnotatedChecks(SqlVarNameChecker.class);
}
@Override
public void describe(SensorDescriptor descriptor) {
//传感器名称
descriptor.name("FlagLine1Rule" + "sensor");
//传感器识别的语言
descriptor.onlyOnLanguages(CxxLanguage.KEY);
//传感器扫描的规则库
descriptor.createIssuesForRuleRepository("cxx-security-design-rules");
}
@Override
public void execute(SensorContext context) {
FilePredicates p = context.fileSystem().predicates();
for (InputFile inputFile : context.fileSystem().inputFiles(p.hasLanguages(CxxLanguage.KEY))) {
checks.all().forEach(check -> {
check.execute(context, inputFile, checks.ruleKey(check));
});
}
}
}

@ -1,14 +1,19 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.AbstractLanguage;
import org.sonar.api.resources.Qualifiers;
import java.util.List;
import static java.util.Arrays.asList;
import java.lang.module.Configuration;
/**
* TODO LogLanguage
@ -16,21 +21,35 @@ import java.lang.module.Configuration;
* @author RenFengJiang
* @date 2024/1/16
*/
public final class LogLanguage extends AbstractLanguage {
public class LogLanguage extends AbstractLanguage {
public static final String NAME = "LOG";
public static final String KEY = "log";
private final Configuration config;
public static final String FILE_SUFFIXES_KEY = "sonar.log.file.suffixes";
public LogLanguage( Configuration config) {
public static final String DEFAULT_FILE_SUFFIXES = ".log";
public LogLanguage() {
super(KEY, NAME);
this.config = config;
}
@Override
public String[] getFileSuffixes() {
String[] arr = new String[1];
arr[0] = ".log";
return arr;
return new String[] {".log"};
}
public static List<PropertyDefinition> properties() {
return asList(
PropertyDefinition.builder(FILE_SUFFIXES_KEY)
.multiValues(true)
.defaultValue(DEFAULT_FILE_SUFFIXES)
.category("FileType")
.name("File Suffixes")
.description("List of suffixes for files to analyze.")
.onQualifiers(Qualifiers.PROJECT)
.build()
);
}
}

@ -0,0 +1,31 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx;
import org.sonar.api.server.rule.RulesDefinition;
public class LogRuleRepository implements RulesDefinition {
private static final String REPOSITORY_NAME = "SonarQube";
@Override
public void define(Context context) {
// 创建规则仓库
NewRepository repository = context.createRepository("log", LogLanguage.KEY)
.setName(REPOSITORY_NAME);
// 创建新规则
NewRule errorRecoveryRule = repository.createRule("ParsingErrorRecovery");
errorRecoveryRule.setName("Parsing Error Recovery");
// 为另一个规则设置描述
errorRecoveryRule.setHtmlDescription("<p>This rule checks for parsing error recovery issues</p>");
// 完成规则创建
repository.done();
}
}

@ -1,13 +1,14 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx.rules;
import com.keyware.sonar.cxx.CxxLanguage;
import com.keyware.sonar.cxx.rules.checkers.ABCVarNameChecker;
import com.keyware.sonar.cxx.LogLanguage;
import com.keyware.sonar.cxx.rules.checkers.*;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.cxx.squidbridge.annotations.AnnotationBasedRulesDefinition;
@ -22,10 +23,16 @@ import java.util.List;
*/
public class SecurityDesignRuleRepository implements RulesDefinition {
public final static String REPOSITORY_KEY = "cxx-security-design-rules";
public final static String REPOSITORY_log_key = "log-security-design-rules";
public final static String REPOSITORY_NAME = "C++信息安全性设计准则";
// 规则检查器的集合,当有新的规则开发完毕后,需要添加到下面的集合中
public final static List<Class> RULE_CHECKERS = Arrays.asList(ABCVarNameChecker.class);
public final static List<Class> RULE_CHECKERS = Arrays.asList(ABCVarNameChecker.class,BufferDataChecker.class, CmdDataVerifyChecker.class,
DLLVerifyChecker.class,EncryptionAlgorithmChecker.class,ErrorMessageChecker.class,
FileAccessChecker.class,FormatFunctionCheck.class,FVNRPassWordChecker.class,FVNRShaChecker.class,HighEncryptDesChecker.class,
HostIdentityVerifyChecker.class,IntegerCountVerifyChecker.class,LogChecker.class,LogFileWriteChecker.class,NumericalCopyChecker.class,
PassWordCountChecker.class,PathVerifyChecker.class,PRNGVerifyChecker.class,ReallocMainChecker.class,SendMessageChecker.class,
SQLVerifyChecker.class,UserInputPasswordChecker.class,ValidatePasswordCheck.class,VerificationPathChecker.class,VirtualLockUsageChecker.class);
@Override
public void define(Context context) {
@ -33,5 +40,10 @@ public class SecurityDesignRuleRepository implements RulesDefinition {
setName(REPOSITORY_NAME);
new AnnotationBasedRulesDefinition(repository, CxxLanguage.KEY).addRuleClasses(false, RULE_CHECKERS);
repository.done();
var repository1 = context.createRepository(REPOSITORY_log_key, LogLanguage.KEY).
setName(REPOSITORY_NAME);
new AnnotationBasedRulesDefinition(repository1, LogLanguage.KEY).addRuleClasses(false, RULE_CHECKERS);
repository1.done();
}
}

@ -1,12 +1,13 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx.rules;
import com.keyware.sonar.cxx.CxxLanguage;
import com.keyware.sonar.cxx.LogLanguage;
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
import org.sonarsource.api.sonarlint.SonarLintSide;
@ -22,6 +23,35 @@ public class SecurityDesignWayProfile implements BuiltInQualityProfilesDefinitio
public void define(Context context) {
var way = context.createBuiltInQualityProfile("C++信息安全性设计准则", CxxLanguage.KEY);
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "ABCVarNameChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "BufferDataChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "CmdDataVerifyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "DLLVerifyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "EncryptionAlgorithmChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "ErrorMessageChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "FileAccessChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "FormatFunctionCheck");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "FVNRPassWordChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "FVNRShaChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "HighEncryptDesChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "HostIdentityVerifyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "IntegerCountVerifyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "LogFileWriteChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "NumericalCopyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "PassWordCountChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "PathVerifyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "PRNGVerifyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "ReallocMainChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "SendMessageChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "FlagLine1Rule");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "SQLVerifyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "UserInputPasswordChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "ValidatePasswordCheck");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "VerificationPathChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "VirtualLockUsageChecker");
way.done();
var way1 = context.createBuiltInQualityProfile("LogLanguage信息安全性设计准则", LogLanguage.KEY);
way1.activateRule(SecurityDesignRuleRepository.REPOSITORY_log_key, "LogChecker");
way1.done();
}
}

@ -1,265 +0,0 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx.rules.checkers;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sonar.cxx.sslr.api.AstNode;
import com.sonar.cxx.sslr.api.Grammar;
import org.sonar.check.Rule;
import org.sonar.cxx.squidbridge.annotations.ActivatedByDefault;
import org.sonar.cxx.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.cxx.squidbridge.checks.SquidCheck;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.yaml.snakeyaml.Yaml;
import javax.annotation.Nullable;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;
/**
* TODO LogChecker
*
* @author WuHaoYang
* @date 2024/1/19
*/
@Rule(key = "ConfigurationFileChecker", name = "避免在容易受攻击的地方存储口令", description = "避免在容易受攻击的地方存储口令")
@ActivatedByDefault
@SqaleConstantRemediation("5min")
public class ConfigurationFileChecker extends SquidCheck<Grammar> {
@Override
public void visitFile(@Nullable AstNode astNode) {
String filename = getContext().getInputFile().filename();
if (filename.endsWith(".properties")) {
try {
File file = new File(getContext().getInputFile().absolutePath());
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.contains("password")) {
System.out.println(line);
getContext().createFileViolation(this, "避免在容易受攻击的地方存储口令");
break;
}
}
}
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
}
}
if (filename.endsWith(".yml")){
// 获取当前输入文件的绝对路径
File inputFile = getContext().getInputFile().file();
String absolutePath = inputFile.getAbsolutePath();
// 构建目录路径
File dir = new File(absolutePath).getParentFile();
Yaml yaml = new Yaml();
for (File file : dir.listFiles()) {
if (file.isFile() && file.getName().endsWith(".yml")) {
try (FileInputStream fis = new FileInputStream(file)) {
Map<String, Object> obj = yaml.load(fis);
if (obj != null){
String password = searchPassword(obj);
if (password != null) {
System.out.println("password="+password);
getContext().createFileViolation(this, "避免在容易受攻击的地方存储口令");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
if (filename.endsWith(".ini")){
// 获取当前输入文件的绝对路径
File inputFile = getContext().getInputFile().file();
String absolutePath = inputFile.getAbsolutePath();
// 构建目录路径
File folder = new File(absolutePath).getParentFile();
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles) {
if (file.isFile() && file.getName().endsWith(".ini")) {
Properties properties = new Properties();
try (FileInputStream fileInput = new FileInputStream(file)) {
properties.load(fileInput);
String password = properties.getProperty("password");
System.out.println("password=" + password);
getContext().createFileViolation(this, "避免在容易受攻击的地方存储口令");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
if (filename.endsWith(".xml")){
// 获取当前输入文件的绝对路径
File inputFile = getContext().getInputFile().file();
String absolutePath = inputFile.getAbsolutePath();
// 构建目录路径
File dir = new File(absolutePath).getParentFile();
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".xml");
}
};
String[] children = dir.list(filter);
if (children == null) {
System.out.println("目录不存在或不是目录");
} else {
for (int i = 0; i < children.length; i++) {
String filename1 = children[i];
File xmlFile = new File(dir, filename1);
processXML(xmlFile);
getContext().createFileViolation(this, "避免在容易受攻击的地方存储口令");
}
}
}
if (filename.endsWith(".json")){
try {
// 获取当前输入文件的绝对路径
File inputFile = getContext().getInputFile().file();
String absolutePath = inputFile.getAbsolutePath();
// 构建目录路径
File folder = new File(absolutePath).getParentFile();
File[] listOfFiles = folder.listFiles();
if (listOfFiles != null) {
ObjectMapper mapper = new ObjectMapper();
for (File file : listOfFiles) {
if (file.isFile() && file.getName().endsWith(".json")) {
JsonNode rootNode = mapper.readTree(file);
extractPassword(rootNode);
getContext().createFileViolation(this, "避免在容易受攻击的地方存储口令");
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (filename.endsWith(".conf")){
// 获取当前输入文件的绝对路径
File inputFile = getContext().getInputFile().file();
String absolutePath = inputFile.getAbsolutePath();
// 构建目录路径
File folder = new File(absolutePath).getParentFile();
File[] listOfFiles = folder.listFiles((dir, name) -> name.endsWith(".conf"));
for (File file : listOfFiles) {
if (file.isFile()) {
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream(file);
prop.load(input);
if (prop.containsKey("password")) {
System.out.println("password="+ prop.getProperty("password"));
getContext().createFileViolation(this, "避免在容易受攻击的地方存储口令");
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
public static void extractPassword(JsonNode node) {
Iterator<String> fieldNames = node.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
if (fieldName.equals("password")) {
System.out.println("Password= " + node.get(fieldName).asText());
}
if (node.get(fieldName).isContainerNode()) {
extractPassword(node.get(fieldName));
}
}
}
public static void processXML(File xmlFile) {
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("password");
for (int i = 0; i < nList.getLength(); i++) {
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("Password="+ eElement.getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String searchPassword(Map<String, Object> map) {
for (String key : map.keySet()) {
if ("password".equals(key) && map.get(key) instanceof String) {
return (String) map.get(key);
} else if (map.get(key) instanceof Map) {
String password = searchPassword((Map<String, Object>) map.get(key));
if (password != null) {
return password;
}
}
}
return null;
}
}

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

@ -0,0 +1,78 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx.rules.checkers;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.cxx.squidbridge.annotations.ActivatedByDefault;
import org.sonar.cxx.squidbridge.annotations.SqaleConstantRemediation;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
/**
* C++规则检查器的实现示例
*
* @author GuoXin
* @date 2024/1/6
*/
@Rule(key = "FlagLine1Rule", name = "sql注入", description = "sql注入有一定风险", priority = Priority.INFO, tags = {"28suo"})
@ActivatedByDefault
@SqaleConstantRemediation("5min")
public class SqlVarNameChecker implements FlagLineRule {
@Override
public void execute(SensorContext sensorContext, InputFile file, RuleKey ruleKey) {
try (Scanner scanner = new Scanner(file.inputStream(), StandardCharsets.UTF_8.name())) {
int lineNumber = 1;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.contains("= '") || line.contains("OR 1=1") || line.contains("='")
|| line.contains("DROP TABLE") || line.contains("' OR 'a'='a") || line.contains("'; DROP TABLE users; --")
|| line.contains("'; EXEC xp_cmdshell 'dir'") || line.contains("' OR username LIKE '%") || line.contains("' AND SLEEP(5)")
|| line.contains("= \\'' +") || line.contains("= ?")) { // 根据特定的关键词或模式匹配来定位 SQL 注入
NewIssue newIssue = sensorContext.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(file)
.at(file.selectLine(lineNumber)))
.save();
}
lineNumber++;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/*
@Override
public void visitNode(AstNode node) {
File file = getContext().getFile();
System.out.println("文件路径: " + file.getAbsolutePath());
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
int lineNumber = 0;
while ((line = reader.readLine()) != null) {
lineNumber++;
if (line.contains("= '") || line.contains("OR 1=1") || line.contains("='")
|| line.contains("DROP TABLE") || line.contains("' OR 'a'='a") || line.contains("'; DROP TABLE users; --")
|| line.contains("'; EXEC xp_cmdshell 'dir'") || line.contains("' OR username LIKE '%") || line.contains("' AND SLEEP(5)")
|| line.contains("= \\'' +") || line.contains("= ?")) {
getContext().createLineViolation(ABCVarNameChecker.this, "sql 注入有一定风险", lineNumber);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}*/
}

@ -1,6 +1,6 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
@ -18,9 +18,11 @@ class CxxRuleRepositoryTest {
var context = new RulesDefinition.Context();
assertThat(context.repositories()).isEmpty();
new CxxRuleRepository().define(context);
new LogRuleRepository().define(context);
assertThat(context.repositories()).hasSize(1);
assertThat(context.repositories()).hasSize(2);
assertThat(context.repository("cxx").rules()).hasSize(27);
assertThat(context.repository("log").rules()).hasSize(1);
}
}

@ -1,72 +0,0 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx.rules.checkers;
import com.keyware.sonar.cxx.CxxFileTesterHelper;
import org.junit.jupiter.api.Test;
import org.sonar.cxx.CxxAstScanner;
import org.sonar.cxx.squidbridge.api.CheckMessage;
import org.sonar.cxx.squidbridge.api.SourceFile;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* TODO ConfigurationFileCheckerTest
*
* @author WuHaoYang
* @date 2024/1/19
*/
public class ConfigurationFileCheckerTest {
@Test
public void checkDirectory() throws IOException {
File folder = new File("src/test/resources/com/keyware/sonar/cxx/rules/checkers/configFile"); // 文件夹路径
File[] files = folder.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".yml") || name.endsWith(".ini") || name.endsWith(".properties") ||
name.endsWith(".xml") || name.endsWith(".json") || name.endsWith(".conf");
}
});
List<String> problems = new ArrayList<>(); // 存储问题的列表
for (File file : files) {
try {
if (file.isFile()) {
var tester = CxxFileTesterHelper.create("configFile/" + file.getName());
System.out.println("配置文件名称:" + file.getName());
var checker = new ConfigurationFileChecker();
SourceFile sourceFile = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
for (CheckMessage message : sourceFile.getCheckMessages()) {
if (message.formatDefaultMessage().equals("避免在容易受攻击的地方存储口令")) {
problems.add("文件:" + file.getName() + " ,问题:" + message.getDefaultMessage());
}
}
}
} catch (Exception e) {
System.out.println("在处理文件时遇到问题:" + file.getName());
e.printStackTrace();
}
}
for (String problem : problems) {
System.out.println(problem);
}
}
}

@ -29,13 +29,13 @@ public class JavaSecurityDesignRulesPlugin implements Plugin {
context.addExtension(JavaFileCheckRegistrar.class);
context.addExtension(ConfigurationFileLanguage.class);
context.addExtension(ConfigFileSquidSensor.class);
context.addExtensions(ConfigurationFileLanguage.getProperties());
// context.addExtension(ConfigurationFileLanguage.class);
//
//
// context.addExtension(ConfigFileSquidSensor.class);
//
//
// context.addExtensions(ConfigurationFileLanguage.getProperties());
}
}

@ -31,9 +31,9 @@ public class JavaSecurityDesignWayProfile implements BuiltInQualityProfilesDefin
RulesList.getHtmlRules().forEach(check -> webWay.activateRule(JavaSecurityDesignRulesRepository.REPOSITORY_KEY + "-" + HtmlConstants.LANGUAGE_KEY, check.getSimpleName()));
webWay.done();
var cfgWay = context.createBuiltInQualityProfile("配置信息安全性设计规则", ConfigurationFileLanguage.KEY);
cfgWay.activateRule("config", "ConfigurationFileChecker");
cfgWay.activateRule("config", "SessionDateChecker");
cfgWay.done();
// var cfgWay = context.createBuiltInQualityProfile("配置信息安全性设计规则", ConfigurationFileLanguage.KEY);
// cfgWay.activateRule("config", "ConfigurationFileChecker");
// cfgWay.activateRule("config", "SessionDateChecker");
// cfgWay.done();
}
}

@ -6,8 +6,6 @@
*/
package com.keyware.sonar.java.rules;
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.SonarProduct;
@ -55,10 +53,10 @@ public class JavaSecurityDesignRulesRepository implements RulesDefinition {
setTemplates(htmlRepo);
htmlRepo.done();
RulesDefinition.NewRepository configRepo = context.createRepository("config", "cfg").setName("config");
ruleMetadataLoader.addRulesByAnnotatedClass(configRepo, List.of(ConfigurationFileChecker.class, SessionDateChecker.class));
setTemplates(configRepo);
configRepo.done();
// RulesDefinition.NewRepository configRepo = context.createRepository("config", "cfg").setName("config");
// ruleMetadataLoader.addRulesByAnnotatedClass(configRepo, List.of(ConfigurationFileChecker.class, SessionDateChecker.class));
// setTemplates(configRepo);
// configRepo.done();
}
private static void setTemplates(RulesDefinition.NewRepository repository) {

@ -1,276 +0,0 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java.rules.checkers;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.check.Rule;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.yaml.snakeyaml.Yaml;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;
/**
* 通过用户名口令数据证书等其他手段对用户身份进行验证
*
* @author WuHaoYang
* @date 2024/1/22
*/
@Rule(key = "ConfigurationFileChecker")
public class ConfigurationFileChecker implements ConfigCheck{
public void execute(SensorContext context, InputFile inputFile, RuleKey ruleKey){
//文件名称
String filename = inputFile.filename();
System.out.println("[ConfigurationFileChecker]>>>>>" + filename);
//校验文件后缀
if (filename.endsWith(".properties")) {
try {
File file = new File(inputFile.absolutePath());
System.out.println("---------------properties文件路径----------------"+file);
try (Scanner scanner = new Scanner(file)) {
int lineNum = 1;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.contains("password")) {
System.out.println(line);
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
break;
}
lineNum ++;
}
}
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
}
}
if (filename.endsWith(".ini")){
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
// 构建目录路径
System.out.println("---------------ini文件路径----------------"+file1);
int lineNum = 1;
Properties properties = new Properties();
try (FileInputStream fileInput = new FileInputStream(file1)) {
properties.load(fileInput);
String password = properties.getProperty("password");
System.out.println("password=" + password);
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
} catch (IOException e) {
e.printStackTrace();
}
lineNum++;
}
if (filename.endsWith(".conf")){
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
// 构建目录路径
System.out.println("---------------conf文件路径----------------"+file1);
int lineNum = 1;
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream(file1);
prop.load(input);
if (prop.containsKey("password")) {
System.out.println("password="+ prop.getProperty("password"));
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
lineNum++;
}
if (filename.endsWith(".xml")){
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
File absoluteFile = file1.getAbsoluteFile();
// 构建目录路径
File dir = new File(String.valueOf(absoluteFile)).getParentFile();
System.out.println("---------------xml文件路径----------------"+file1);
File xmlFile = new File(dir, filename);
processXML(xmlFile);
int lineNum = 1;
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
}
if (filename.endsWith(".json")){
try {
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
File absoluteFile = file1.getAbsoluteFile();
// 构建目录路径
File folder = new File(String.valueOf(absoluteFile)).getParentFile();
System.out.println("---------------json文件路径----------------"+file1);
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(file1);
extractPassword(rootNode);
int lineNum = 1;
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
} catch (IOException e) {
e.printStackTrace();
}
}
if (filename.endsWith(".yml")){
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
File absoluteFile = file1.getAbsoluteFile();
// 构建目录路径
File dir = new File(String.valueOf(absoluteFile)).getParentFile();
System.out.println("---------------yml文件路径----------------"+file1);
Yaml yaml = new Yaml();
try (FileInputStream fis = new FileInputStream(file1)) {
Map<String, Object> obj = yaml.load(fis);
if (obj != null){
String password = searchPassword(obj);
if (password != null) {
System.out.println("password="+password);
int lineNum = 1;
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.selectLine(lineNum)))
.save();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void processXML(File xmlFile) {
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("password");
for (int i = 0; i < nList.getLength(); i++) {
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("Password="+ eElement.getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void extractPassword(JsonNode node) {
Iterator<String> fieldNames = node.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
if (fieldName.equals("password")) {
System.out.println("Password= " + node.get(fieldName).asText());
}
if (node.get(fieldName).isContainerNode()) {
extractPassword(node.get(fieldName));
}
}
}
private static String searchPassword(Map<String, Object> map) {
for (String key : map.keySet()) {
if ("password".equals(key) && map.get(key) instanceof String) {
return (String) map.get(key);
} else if (map.get(key) instanceof Map) {
String password = searchPassword((Map<String, Object>) map.get(key));
if (password != null) {
return password;
}
}
}
return null;
}
}

@ -39,10 +39,11 @@ public class JavaSecurityDesignRulesPluginTest {
.containsExactlyInAnyOrder(
"JavaSecurityDesignRulesRepository",
"JavaSecurityDesignWayProfile",
"JavaFileCheckRegistrar",
"ConfigurationFileLanguage",
"ConfigFileSquidSensor",
"File Suffixes");
"JavaFileCheckRegistrar"
// "ConfigurationFileLanguage",
// "ConfigFileSquidSensor",
// "File Suffixes"
);
}
public static class MockedSonarRuntime implements SonarRuntime {

Loading…
Cancel
Save