parent
0061c15772
commit
3818b0832d
@ -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() |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -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,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,2 @@ |
|||||||
|
# 这是一个conf配置文件 |
||||||
|
password = yourpassword |
@ -0,0 +1,3 @@ |
|||||||
|
[UserCredentials] |
||||||
|
username = exampleUser |
||||||
|
password = examplePassword |
@ -0,0 +1,2 @@ |
|||||||
|
# ConfigurationFileChecker.properties |
||||||
|
password=abc123 |
Loading…
Reference in new issue