Merge remote-tracking branch 'origin/master'

wuhaoyang
Guo XIn 10 months ago
commit 4156850164
  1. 93
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.java
  2. 35
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyCheckerTest.java
  3. 7
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.cc
  4. 69
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/ConfigFileSquidSensor.java
  5. 60
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/ConfigurationFileLanguage.java
  6. 9
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/JavaSecurityDesignRulesPlugin.java
  7. 4
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/JavaSecurityDesignWayProfile.java
  8. 13
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/JavaSecurityDesignRulesRepository.java
  9. 149
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/ConfigurationFileChecker.java
  10. 90
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java
  11. 9
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/ConfigurationFileChecker.html
  12. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/ConfigurationFileChecker.json
  13. 16
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/OptionsVerifyChecker.html
  14. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/OptionsVerifyChecker.json
  15. 33
      sonar-keyware-plugins-java/src/test/files/OptionsVerifyRule.java
  16. 2
      sonar-keyware-plugins-java/src/test/files/configFile/ConfigurationFileChecker.conf
  17. 3
      sonar-keyware-plugins-java/src/test/files/configFile/ConfigurationFileChecker.ini
  18. 2
      sonar-keyware-plugins-java/src/test/files/configFile/ConfigurationFileChecker.properties
  19. 33
      sonar-keyware-plugins-java/src/test/files/options/OptionsVerifyOneRule.java
  20. 27
      sonar-keyware-plugins-java/src/test/files/options/OptionsVerifyTwoRule.java
  21. 16
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/JavaSecurityDesignRulesPluginTest.java
  22. 39
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java

@ -0,0 +1,93 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.cxx.rules.checkers;
import com.sonar.cxx.sslr.api.AstNode;
import com.sonar.cxx.sslr.api.Grammar;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.squidbridge.annotations.ActivatedByDefault;
import org.sonar.cxx.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.cxx.squidbridge.checks.SquidCheck;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 使用关键资源时指定资源所在的路径
* 1.获取到声明预计
* 2.判断是不是路径
* 3.判断是不是绝对路径
*
* @author RenFengJiang
* @date 2024/1/22
*/
@Rule(key = "PathVerifyChecker", name = "使用关键资源时指定资源所在的路径", description = "使用关键资源时指定资源所在的路径", priority = Priority.INFO, tags = {"28suo"})
@ActivatedByDefault
@SqaleConstantRemediation("5min")
public class PathVerifyChecker extends SquidCheck<Grammar> {
@Override
public void init() {
// 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点
this.subscribeTo(
CxxGrammarImpl.declarationStatement
);
}
/**
* 访问AST节点
*
* @param node 要处理的AST节点该节点类型为通过subscribeTo方法订阅的类型
*/
@Override
public void visitNode(@Nonnull AstNode node) {
//获取参数
AstNode firstDescendant = node.getFirstDescendant(CxxGrammarImpl.initializer);
List<AstNode> children = firstDescendant.getChildren();
for(AstNode chil : children){
//判断参数类型
if("STRING".equals(chil.getName())){
String result = chil.getTokenValue().replace("\"", "");
if(isPath(result)){
//判断是不是windows或linux的绝对路径
if(!isWindowsAbsolutePath(result) && !isLinuxAbsolutePath(result)){
getContext().createLineViolation(this, "使用关键资源时指定资源所在的路径", chil);
}
}
}
}
}
//判断是不是路径
public static boolean isPath(String str) {
// 检查字符串是否至少包含一个有效的路径分隔符
return (str.contains("/") || str.contains("\\")); // 注意:Java中需要双反斜杠来表示单个反斜杠字符
}
//windows下判断是否是绝对路径
public static boolean isWindowsAbsolutePath(String path) {
// 正则表达式匹配以驱动器号(如C:)开始的路径
String regex = "^([A-Za-z]):\\\\.*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(path);
return matcher.matches();
}
//判断linux下判断是否是绝对路径
public static boolean isLinuxAbsolutePath(String path) {
// 正则表达式匹配以根目录(/)开始的路径
String regex = "^/";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(path);
return matcher.find(); // 使用find()而不是matches(),因为matches()要求整个字符串都符合模式
}
}

@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的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.SourceFile;
import org.sonar.cxx.squidbridge.checks.CheckMessagesVerifier;
import java.io.IOException;
/**
* TODO PathVerifyCheckerTest
*
* @author RenFengJiang
* @date 2024/1/22
*/
public class PathVerifyCheckerTest {
@Test
public void checkTest() throws IOException {
var checker = new PathVerifyChecker();
var tester = CxxFileTesterHelper.create("PathVerifyChecker.cc");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(3).withMessage("使用关键资源时指定资源所在的路径")
.next().atLine(4).withMessage("使用关键资源时指定资源所在的路径")
.noMore();
}
}

@ -0,0 +1,7 @@
int main() {
//std::String a = "/path/to/your/file.txt";
std::String a = "path/to/your/file.txt";
std::String testString1 = "User\\Documents";
//std::String testString1 = "C:\\Users\\User\\Documents";
return 0;
}

@ -0,0 +1,69 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java;
import com.keyware.sonar.java.rules.checkers.ConfigurationFileChecker;
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;
import org.sonar.api.measures.CoreMetrics;
import java.io.IOException;
public class ConfigFileSquidSensor implements Sensor {
private final Checks<ConfigurationFileChecker> checks;
private SensorContext context;
public ConfigFileSquidSensor(CheckFactory checkFactory){
checks = checkFactory.create("config");
checks.addAnnotatedChecks(ConfigurationFileChecker.class);
}
@Override
public void describe(SensorDescriptor descriptor) {
descriptor
.name("ConfigSquidSensor")
.onlyOnLanguages(ConfigurationFileLanguage.KEY)
.createIssuesForRuleRepository("config");
}
@Override
public void execute(SensorContext context) {
FilePredicates p = context.fileSystem().predicates();
for (InputFile inputFile : context.fileSystem().inputFiles(p.hasLanguages(ConfigurationFileLanguage.KEY))) {
checks.all().forEach(check -> {
check.execute(context, inputFile, checks.ruleKey(check));
});
}
}
private String readFileContents(InputFile javaFile) {
String content;
try {
content = javaFile.contents();
} catch (IOException e) {
System.err.println("Failed to read " + javaFile + " due to " + e.getMessage());
content = "";
}
return content;
}
private void measureLines(SensorContext context, InputFile javaFile, String content) {
int lines = content.split("[\n\r]").length;
context.<Integer>newMeasure()
.forMetric(CoreMetrics.NCLOC)
.on(javaFile)
.withValue(lines)
.save();
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.AbstractLanguage;
import org.sonar.api.resources.Qualifiers;
import java.util.Arrays;
import java.util.List;
import static java.util.Arrays.asList;
public class ConfigurationFileLanguage extends AbstractLanguage {
public static final String NAME = "Configuration";
public static final String KEY = "cfg";
public static final String FILE_SUFFIXES_KEY = "sonar.disposition.file.suffixes";
public static final String FILE_SUFFIXES_DEFAULT_VALUE = ".properties,.ini,.conf";
private final Configuration config;
public ConfigurationFileLanguage(Configuration config) {
super(KEY, NAME);
this.config = config;
}
@Override
public String[] getFileSuffixes() {
String[] suffixes = config.getStringArray(FILE_SUFFIXES_KEY);
if (suffixes == null || suffixes.length == 0) {
return FILE_SUFFIXES_DEFAULT_VALUE.split(",");
}
// 修剪空格和小写后缀
return Arrays.stream(suffixes)
.map(String::trim)
.map(String::toLowerCase)
.toArray(String[]::new);
}
public static List<PropertyDefinition> getProperties() {
return asList(
PropertyDefinition.builder(FILE_SUFFIXES_KEY)
.multiValues(true)
.defaultValue(FILE_SUFFIXES_DEFAULT_VALUE)
.category("FileType")
.name("File Suffixes")
.description("List of suffixes for files to analyze.")
.onQualifiers(Qualifiers.PROJECT)
.build()
);
}
}

@ -28,5 +28,14 @@ public class JavaSecurityDesignRulesPlugin implements Plugin {
// 批处理扩展 - >对象在代码分析期间实例化
context.addExtension(JavaFileCheckRegistrar.class);
context.addExtension(ConfigurationFileLanguage.class);
context.addExtension(ConfigFileSquidSensor.class);
context.addExtensions(ConfigurationFileLanguage.getProperties());
}
}

@ -30,5 +30,9 @@ public class JavaSecurityDesignWayProfile implements BuiltInQualityProfilesDefin
var webWay = context.createBuiltInQualityProfile("Web信息安全性设计准则", HtmlConstants.LANGUAGE_KEY);
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.done();
}
}

@ -6,6 +6,7 @@
*/
package com.keyware.sonar.java.rules;
import com.keyware.sonar.java.rules.checkers.ConfigurationFileChecker;
import org.sonar.api.SonarEdition;
import org.sonar.api.SonarProduct;
import org.sonar.api.SonarQubeSide;
@ -15,10 +16,7 @@ import org.sonar.api.utils.Version;
import org.sonar.plugins.html.api.HtmlConstants;
import org.sonarsource.analyzer.commons.RuleMetadataLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
import java.util.*;
/**
* 用于定义出现在规则页面中规则的元数据
@ -50,10 +48,15 @@ public class JavaSecurityDesignRulesRepository implements RulesDefinition {
setTemplates(javaRepo);
javaRepo.done();
RulesDefinition.NewRepository htmlRepo = context.createRepository(REPOSITORY_KEY + "-" + HtmlConstants.LANGUAGE_KEY, HtmlConstants.LANGUAGE_KEY).setName(REPOSITORY_NAME);
RulesDefinition.NewRepository htmlRepo = context.createRepository(REPOSITORY_KEY + "-" + HtmlConstants.LANGUAGE_KEY, HtmlConstants.LANGUAGE_KEY).setName("web");
ruleMetadataLoader.addRulesByAnnotatedClass(htmlRepo, new ArrayList<>(RulesList.getHtmlRules()));
setTemplates(htmlRepo);
htmlRepo.done();
RulesDefinition.NewRepository configRepo = context.createRepository("config", "cfg").setName("config");
ruleMetadataLoader.addRulesByAnnotatedClass(configRepo, List.of(ConfigurationFileChecker.class));
setTemplates(configRepo);
configRepo.done();
}
private static void setTemplates(RulesDefinition.NewRepository repository) {

@ -0,0 +1,149 @@
/*
* 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.batch.sensor.issue.NewIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.check.Rule;
import java.io.*;
import java.util.Properties;
import java.util.Scanner;
/**
* TODO ConfigurationFileChecker
*
* @author WuHaoYang
* @date 2024/1/22
*/
@Rule(key = "ConfigurationFileChecker")
public class ConfigurationFileChecker {
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();
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();
File absoluteFile = file1.getAbsoluteFile();
// 构建目录路径
File folder = new File(String.valueOf(absoluteFile)).getParentFile();
System.out.println("---------------ini文件路径----------------"+folder);
File[] listOfFiles = folder.listFiles();
int lineNum = 1;
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);
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();
File absoluteFile = file1.getAbsoluteFile();
// 构建目录路径
File folder = new File(String.valueOf(absoluteFile)).getParentFile();
System.out.println("---------------conf文件路径----------------"+folder);
File[] listOfFiles = folder.listFiles((dir, name) -> name.endsWith(".conf"));
int lineNum = 1;
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"));
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++;
}
}
}
}

@ -0,0 +1,90 @@
/*
* 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.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.DefaultModuleScannerContext;
import org.sonar.java.model.expression.LiteralTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.java.model.expression.MethodInvocationTreeImpl;
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.Arguments;
import org.sonar.plugins.java.api.tree.ExpressionTree;
import org.sonar.plugins.java.api.tree.Tree;
import java.util.Collections;
import java.util.List;
/**
* 应设置X-Frame-Options的值为deny
* 1.获取所有方法调用节点
* 2.判断方法中的参数是否否和要求
*
* @author RenFengJiang
* @date 2024/1/22
*/
@Rule(key = "OptionsVerifyChecker")
public class OptionsVerifyChecker extends IssuableSubscriptionVisitor implements EndOfAnalysis {
private boolean boo = true;
@Override
public List<Tree.Kind> nodesToVisit() {
/**
* Tree.Kind.METHOD方法节点
* Tree.Kind.BLOCK方法的代码块节点
* Tree.Kind.METHOD_INVOCATION 方法的调用节点
*/
return Collections.singletonList(Tree.Kind.METHOD_INVOCATION);
}
@Override
public void visitNode(Tree tree) {
//判断项目是否配置
if(boo){
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) tree;
ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if(expressionTree instanceof MemberSelectExpressionTreeImpl){
MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
//获取到调用方法判断是否是设置配置方法
if("addHeader".equals(selectExpressionTree.identifier().name()) || "setHeader".equals(selectExpressionTree.identifier().name())){
//获取方法参数
Arguments arguments = methodInvocationTree.arguments();
if(arguments instanceof ArgumentListTreeImpl){
boolean one = false;
boolean two = false;
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) {
if(argument instanceof LiteralTreeImpl){
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument;
//判断参数
if("\"X-Frame-Options\"".equals(literalTree.token().text())){
one = true;
}else if("\"DENY\"".equals(literalTree.token().text())){
two = true;
}
}
}
if(one && two){
boo = false;
}
}
}
}
}
}
@Override
public void endOfAnalysis(ModuleScannerContext context) {
var defaultContext = (DefaultModuleScannerContext) context;
if(boo){
defaultContext.addIssueOnProject(this, "应设置X-Frame-Options的值为deny");
}
}
}

@ -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>应设置X-Frame-Options的值为deny(表示页面不允许在frame中展示)或SAMEORIGIN(表示页面可以在相同域名页面的frame中展示),禁止网页被未信任源加载。</p>
<h2>应设置X-Frame-Options的值为deny</h2>
<pre>
</pre>
<h2>合规解决方案</h2>
<pre>
</pre>

@ -0,0 +1,13 @@
{
"title": "应设置X-Frame-Options的值为deny",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"28suo"
],
"defaultSeverity": "Minor"
}

@ -0,0 +1,33 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class OptionsVerifyChecker implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("X-Frame-Options", "DENY");
chain.doFilter(request, response);
}
@Override
public void destroy() {}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.setHeader("X-Frame-Options", "DENY"); // 或者使用SAMEORIGIN,ALLOW-FROM等其他策略
filterChain.doFilter(request, response);
}
}

@ -0,0 +1,2 @@
# 这是一个conf配置文件
password = yourpassword

@ -0,0 +1,3 @@
[UserCredentials]
username = exampleUser
password = examplePassword

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

@ -0,0 +1,33 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class XFrameOptionsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// response.setHeader("X-Frame-Options", "DENY"); // 或者使用SAMEORIGIN,ALLOW-FROM等其他策略
filterChain.doFilter(request, response);
}
}
// 注册过滤器
public class WebConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// ...其他配置...
Dynamic registration = servletContext.addFilter("xFrameOptionsFilter", new XFrameOptionsFilter());
registration.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
}
}

@ -0,0 +1,27 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class XFrameOptionsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
// res.addHeader("X-Frame-Options", "DENY");
chain.doFilter(request, response);
}
@Override
public void destroy() {}
}

@ -8,6 +8,7 @@ package com.keyware.sonar.java;
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;
@ -26,11 +27,22 @@ public class JavaSecurityDesignRulesPluginTest {
new JavaSecurityDesignRulesPlugin().define(context);
assertThat(context.getExtensions())
.extracting(ext -> ((Class) ext).getSimpleName())
.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(
"JavaSecurityDesignRulesRepository",
"JavaSecurityDesignWayProfile",
"JavaFileCheckRegistrar");
"JavaFileCheckRegistrar",
"ConfigurationFileLanguage",
"ConfigFileSquidSensor",
"File Suffixes");
}
public static class MockedSonarRuntime implements SonarRuntime {

@ -0,0 +1,39 @@
/*
* 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;
import java.util.ArrayList;
import java.util.Collection;
/**
* TODO OptionsVerifyCheckerTest
*
* @author RenFengJiang
* @date 2024/1/22
*/
public class OptionsVerifyCheckerTest {
Collection<String> lists = new ArrayList(){
{
add("src/test/files/options/OptionsVerifyOneRule.java");
add("src/test/files/options/OptionsVerifyTwoRule.java");
}
};
@Test
void detected() {
CheckVerifier.newVerifier()
.onFiles(lists)
.withCheck(new OptionsVerifyChecker())
.withClassPath(FilesUtils.getClassPath("target/test-jars"))
.verifyIssueOnProject("应设置X-Frame-Options的值为deny");
}
}
Loading…
Cancel
Save