Compare commits

..

No commits in common. 'master' and 'wuhaoyang' have entirely different histories.

  1. 2
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/ConfigurationFileLanguage.java
  2. 108
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/rules/checkers/ConfigurationFileChecker.java
  3. 44
      sonar-keyware-plugins-ConfigurationDetection/src/main/java/com/keyware/sonar/Configuration/rules/checkers/SessionDateChecker.java
  4. 7
      sonar-keyware-plugins-cxx/pom.xml
  5. 159
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxSquidSensor.java
  6. 7
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/FlagLineSensor.java
  7. 15
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/SecurityDesignRuleRepository.java
  8. 7
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/SecurityDesignWayProfile.java
  9. 16
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.java
  10. 10
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/CmdDataVerifyChecker.java
  11. 114
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.java
  12. 47
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.java
  13. 29
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ErrorMessageChecker.java
  14. 2
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.java
  15. 13
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRShaChecker.java
  16. 122
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.java
  17. 12
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/HighEncryptDesChecker.java
  18. 40
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.java
  19. 52
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/LogFileWriteChecker.java
  20. 25
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/NumericalCopyChecker.java
  21. 20
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyChecker.java
  22. 70
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountChecker.java
  23. 103
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.java
  24. 2
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ReallocMainChecker.java
  25. 38
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyChecker.java
  26. 46
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.java
  27. 24
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SqlVarNameChecker.java
  28. 93
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.java
  29. 43
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ValidatePasswordCheck.java
  30. 136
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathChecker.java
  31. 42
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.java
  32. 259
      sonar-keyware-plugins-cxx/src/main/java/org/sonar/cxx/squidbridge/AstScanner.java
  33. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/BufferDataCheckerTest.java
  34. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyCheckerTest.java
  35. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmCheckerTest.java
  36. 3
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/FileAccessCheckerTest.java
  37. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyCheckerTest.java
  38. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/NumericalCopyTest.java
  39. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyCheckerTest.java
  40. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountCheckerTest.java
  41. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyCheckerTest.java
  42. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/ReallocMainCheckerTest.java
  43. 3
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyCheckerTest.java
  44. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SendMessageCheckerTest.java
  45. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordCheckerTest.java
  46. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathCheckerTest.java
  47. 3
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageCheckerTest.java
  48. 14
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.cc
  49. 6
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.cc
  50. 2
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.cc
  51. 7
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.cc
  52. 5
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.cc
  53. 9
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.cc
  54. 24
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/LogChecker.log
  55. 18
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/NumericalCopyChecker.cc
  56. 4
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyChecker.cc
  57. 26
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/PassWordCountChecker.cc
  58. 24
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.cc
  59. 58
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/SQLVerifyChecker.cc
  60. 2
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.cc
  61. 14
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.cc
  62. 7
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/VerificationPathChecker.cc
  63. 7
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.cc
  64. 62
      sonar-keyware-plugins-java/pom.xml
  65. 66
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/Java.java
  66. 200
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/KeyJavaSensor.java
  67. 1
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/JavaFileCheckRegistrar.java
  68. 1
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/JavaSecurityDesignRulesRepository.java
  69. 4
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java
  70. 4
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/AuthenticationChecker.java
  71. 18
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/CookieSensitiveParameterCheck.java
  72. 22
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/DynamicCodeChecker.java
  73. 2
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/DynamicLibraryLoadChecker.java
  74. 26
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/FileCheck.java
  75. 64
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java
  76. 80
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HostIdentityChecker.java
  77. 48
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HttpInputDataChecker.java
  78. 25
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/InputSQLVerifyChecker.java
  79. 64
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/Md5PassWordVerifyChecker.java
  80. 106
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java
  81. 85
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordInputTagJavaChecker.java
  82. 92
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordRegexCheck.java
  83. 88
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java
  84. 63
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RedirectUrlChecker.java
  85. 40
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SecurityCookieChecker.java
  86. 10
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SendMessageVerifyChecker.java
  87. 70
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionCacheParamsChecker.java
  88. 4
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/SessionDateChecker.java
  89. 59
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UploadFileVerifyChecker.java
  90. 34
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java
  91. 61
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UserStatusVerifyChecker.java
  92. 4
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/AuthenticationChecker.html
  93. 2
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/AuthenticationChecker.json
  94. 16
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HostIdentityChecker.html
  95. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/HostIdentityChecker.json
  96. 16
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/PasswordInputTagJavaChecker.html
  97. 13
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/PasswordInputTagJavaChecker.json
  98. 33
      sonar-keyware-plugins-java/src/main/resources/org/sonar/l10n/java/rules/java/Sonar_way_profile.json
  99. 26
      sonar-keyware-plugins-java/src/test/files/FileCheck.java
  100. 20
      sonar-keyware-plugins-java/src/test/files/HashSaltPassWordRule.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -21,7 +21,7 @@ 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,.yml,.json";
public static final String FILE_SUFFIXES_DEFAULT_VALUE = ".properties,.ini,.conf,.xml,.yml,.json";
private final Configuration config;

@ -15,8 +15,15 @@ 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;
@ -124,35 +131,15 @@ public class ConfigurationFileChecker implements ConfigCheck{
}
}
if (filename.endsWith(".xml") && !filename.equals("pom.xml")) {
if (filename.endsWith(".xml") && !filename.equals("pom.xml")){
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
File absoluteFile = file1.getAbsoluteFile();
BufferedReader reader = null;
int lineNumber = 0;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file1), "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
lineNumber++;
if (line.contains("<password>")) {
// 创建和保存issue
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation().on(inputFile)
.at(inputFile.selectLine(lineNumber)))
.save();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try { reader.close(); } catch (IOException e) { e.printStackTrace(); }
}
}
File xmlFile = absoluteFile;
processXML(xmlFile);
}
if (filename.endsWith(".json")) {
@ -194,29 +181,70 @@ public class ConfigurationFileChecker implements ConfigCheck{
}
}
if (filename.endsWith(".yml")) {
File file = inputFile.file();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
int lineNumber = 0;
if (filename.endsWith(".yml")){
while ((line = reader.readLine()) != null) {
lineNumber++;
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
if (line.trim().startsWith("password:")) {
// 创建并保存issue
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation().on(inputFile)
.at(inputFile.selectLine(lineNumber)))
.save();
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();
}
}
}

@ -13,7 +13,10 @@ import org.sonar.api.rule.RuleKey;
import org.sonar.check.Rule;
import org.yaml.snakeyaml.Yaml;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;
import java.util.Scanner;
@ -26,36 +29,11 @@ import java.util.Scanner;
@Rule(key = "SessionDateChecker")
public class SessionDateChecker implements ConfigCheck {
private boolean boo = false;
private boolean boo = true;
public void execute(SensorContext context, InputFile inputFile, RuleKey ruleKey){
if(!boo){
if(boo){
//文件名称
String filename = inputFile.filename();
if (filename.endsWith(".xml")) {
// 获取当前输入文件的绝对路径
File file1 = inputFile.file();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file1), "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("<session-timeout>-1</session-timeout>")) {
boo = true;
break;
}
}
} catch (Exception e) {
System.out.println("文件未找到: " + e.getMessage());
return; // 文件未找到时立即返回
} finally {
if (reader != null) {
try { reader.close(); } catch (IOException e) { e.printStackTrace(); }
}
}
}
//校验文件后缀
if (filename.endsWith(".properties")) {
try {
@ -63,8 +41,8 @@ public class SessionDateChecker implements ConfigCheck {
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (!line.contains("server.servlet.session.timeout")) {
boo = true;
if (line.contains("server.servlet.session.timeout")) {
boo = false;
break;
}
}
@ -84,8 +62,8 @@ public class SessionDateChecker implements ConfigCheck {
Map<String, Object> obj = yaml.load(fis);
if (obj != null){
String sessionTimeout = searchForSessionTimeout(obj, "server", "servlet", "session", "timeout");
if (sessionTimeout == null) {
boo = true;
if (sessionTimeout != null) {
boo = false;
}
}
} catch (IOException e) {
@ -99,7 +77,7 @@ public class SessionDateChecker implements ConfigCheck {
Map<String, Object> currentLevel = map;
for (int i = 0; i < keys.length - 1; ++i) {
Object nextLevel = currentLevel.get(keys[i]);
if (nextLevel != null && nextLevel instanceof Map) {
if (nextLevel instanceof Map) {
currentLevel = (Map<String, Object>) nextLevel;
} else {
return null;

@ -124,13 +124,6 @@
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
</dependencies>

@ -308,16 +308,16 @@ public class CxxSquidSensor implements ProjectSensor {
visitors.add(check);
}
}
var squidConfig = createConfiguration();
var scanner = CxxAstScanner.create(squidConfig, visitors.toArray(new SquidAstVisitor[visitors.size()]));
}
var squidConfig = createConfiguration();
var scanner = CxxAstScanner.create(squidConfig, visitors.toArray(new SquidAstVisitor[visitors.size()]));
Iterable<InputFile> inputFiles = getInputFiles(context, squidConfig);
scanner.scanInputFiles(inputFiles);
Iterable<InputFile> inputFiles = getInputFiles(context, squidConfig);
scanner.scanInputFiles(inputFiles);
Collection<SourceCode> squidSourceFiles = scanner.getIndex().search();
save(squidSourceFiles);
}
Collection<SourceCode> squidSourceFiles = scanner.getIndex().search();
save(squidSourceFiles);
}
@Override
@ -428,10 +428,10 @@ public class CxxSquidSensor implements ProjectSensor {
private void saveMeasures(InputFile inputFile, SourceCode sourceCode) {
InputComponent input = inputFile;
if (sourceCode instanceof SourceFile) {
if(sourceCode instanceof SourceFile){
// NOSONAR
noSonarFilter.noSonarInFile(inputFile, ((SourceFile) sourceCode).getNoSonarTagLines());
} else {
noSonarFilter.noSonarInFile(inputFile, ((SourceFile)sourceCode).getNoSonarTagLines());
}else{
input = context.project();
}
@ -501,27 +501,23 @@ public class CxxSquidSensor implements ProjectSensor {
RuleKey ruleKey = checks.ruleKey(checker);
if (ruleKey != null) {
try {
var newIssue = context.newIssue().forRule(RuleKey.of(repositoryKey, ruleKey.rule()));
var location = newIssue.newLocation();
if (sourceCode instanceof SourceFile) {
location.on(inputFile).at(inputFile.selectLine(line));
} else {
location.on(context.project());
}
location.message(message.getText(Locale.CHINA));
newIssue.at(location);
newIssue.save();
} catch (Exception e) {
LOG.error("save issue error, rule key: {}", message);
var newIssue = context.newIssue().forRule(RuleKey.of(repositoryKey, ruleKey.rule()));
var location = newIssue.newLocation();
if(sourceCode instanceof SourceFile){
location.on(inputFile).at(inputFile.selectLine(line));
}else{
location.on(context.project());
}
location.message(message.getText(Locale.CHINA));
newIssue.at(location);
newIssue.save();
} else {
LOG.debug("Unknown rule key: %s", message);
}
}
}
if (sourceCode instanceof SourceFile) {
if(sourceCode instanceof SourceFile) {
var sourceFile = (SourceFile) sourceCode;
if (MultiLocatitionSquidCheck.hasMultiLocationCheckMessages(sourceFile)) {
for (var issue : MultiLocatitionSquidCheck.getMultiLocationCheckMessages(sourceFile)) {
@ -546,102 +542,79 @@ public class CxxSquidSensor implements ProjectSensor {
}
private void saveFileLinesContext(InputFile inputFile, SourceCode sourceCode) {
if (sourceCode instanceof SourceProject || inputFile == null) {
if(sourceCode instanceof SourceProject || inputFile == null){
return;
}
// measures for the lines of file
var fileLinesContext = fileLinesContextFactory.createFor(inputFile);
List<Integer> linesOfCode = (List<Integer>) sourceCode.getData(CxxMetric.NCLOC_DATA);
if (linesOfCode != null && !linesOfCode.isEmpty()) {
linesOfCode.stream().sequential().distinct().forEach((line) -> {
try {
fileLinesContext.setIntValue(CoreMetrics.NCLOC_DATA_KEY, line, 1);
} catch (IllegalArgumentException | IllegalStateException e) {
// ignore errors: parsing errors could lead to wrong location data
LOG.debug("NCLOC error in file '{}' at line:{}", inputFile.filename(), line);
}
});
}
linesOfCode.stream().sequential().distinct().forEach((line) -> {
try {
fileLinesContext.setIntValue(CoreMetrics.NCLOC_DATA_KEY, line, 1);
} catch (IllegalArgumentException | IllegalStateException e) {
// ignore errors: parsing errors could lead to wrong location data
LOG.debug("NCLOC error in file '{}' at line:{}", inputFile.filename(), line);
}
});
List<Integer> executableLines = (List<Integer>) sourceCode.getData(CxxMetric.EXECUTABLE_LINES_DATA);
if (executableLines != null && !executableLines.isEmpty()) {
executableLines.stream().sequential().distinct().forEach((line) -> {
try {
fileLinesContext.setIntValue(CoreMetrics.EXECUTABLE_LINES_DATA_KEY, line, 1);
} catch (IllegalArgumentException | IllegalStateException e) {
// ignore errors: parsing errors could lead to wrong location data
LOG.debug("EXECUTABLE LINES error in file '{}' at line:{}", inputFile.filename(), line);
}
});
}
try {
fileLinesContext.save();
}catch (Exception e){
LOG.error(e.getMessage());
}
executableLines.stream().sequential().distinct().forEach((line) -> {
try {
fileLinesContext.setIntValue(CoreMetrics.EXECUTABLE_LINES_DATA_KEY, line, 1);
} catch (IllegalArgumentException | IllegalStateException e) {
// ignore errors: parsing errors could lead to wrong location data
LOG.debug("EXECUTABLE LINES error in file '{}' at line:{}", inputFile.filename(), line);
}
});
fileLinesContext.save();
}
private void saveCpdTokens(InputFile inputFile, SourceCode sourceCode) {
if (sourceCode instanceof SourceProject || inputFile == null) {
if(sourceCode instanceof SourceProject || inputFile == null){
return;
}
NewCpdTokens cpdTokens = context.newCpdTokens().onFile(inputFile);
List<CxxCpdVisitor.CpdToken> data = (List<CxxCpdVisitor.CpdToken>) sourceCode.getData(CxxMetric.CPD_TOKENS_DATA);
if (data != null && !data.isEmpty()) {
data.forEach((item) -> {
try {
TextRange range = inputFile.newRange(item.startLine, item.startCol, item.endLine, item.endCol);
cpdTokens.addToken(range, item.token);
} catch (IllegalArgumentException | IllegalStateException e) {
// ignore range errors: parsing errors could lead to wrong location data
LOG.debug("CPD error in file '{}' at line:{}, column:{}", inputFile.filename(), item.startLine, item.startCol);
}
});
}
data.forEach((item) -> {
try {
TextRange range = inputFile.newRange(item.startLine, item.startCol, item.endLine, item.endCol);
cpdTokens.addToken(range, item.token);
} catch (IllegalArgumentException | IllegalStateException e) {
// ignore range errors: parsing errors could lead to wrong location data
LOG.debug("CPD error in file '{}' at line:{}, column:{}", inputFile.filename(), item.startLine, item.startCol);
}
});
cpdTokens.save();
}
private void saveHighlighting(InputFile inputFile, SourceCode sourceCode) {
if (sourceCode instanceof SourceProject || inputFile == null) {
if(sourceCode instanceof SourceProject || inputFile == null){
return;
}
NewHighlighting newHighlighting = context.newHighlighting().onFile(inputFile);
List<CxxHighlighterVisitor.Highlight> data = (List<CxxHighlighterVisitor.Highlight>) sourceCode.getData(
CxxMetric.HIGHLIGTHING_DATA);
if(data != null && !data.isEmpty()){
data.forEach((item) -> {
try {
newHighlighting.highlight(item.startLine, item.startLineOffset, item.endLine, item.endLineOffset,
TypeOfText.forCssClass(item.typeOfText));
} catch (IllegalArgumentException | IllegalStateException e) {
// ignore highlight errors: parsing errors could lead to wrong location data
LOG.debug("Highlighting error in file '{}' at start:{}:{} end:{}:{}", inputFile.filename(),
item.startLine, item.startLineOffset, item.endLine, item.endLineOffset);
}
});
}
data.forEach((item) -> {
try {
newHighlighting.highlight(item.startLine, item.startLineOffset, item.endLine, item.endLineOffset,
TypeOfText.forCssClass(item.typeOfText));
} catch (IllegalArgumentException | IllegalStateException e) {
// ignore highlight errors: parsing errors could lead to wrong location data
LOG.debug("Highlighting error in file '{}' at start:{}:{} end:{}:{}", inputFile.filename(),
item.startLine, item.startLineOffset, item.endLine, item.endLineOffset);
}
});
try {
newHighlighting.save();
}catch (Exception e){
LOG.error(e.getMessage());
}
newHighlighting.save();
}
private <T extends Serializable> void saveMetric(InputComponent file, Metric<T> metric, T value) {
try {
context.<T>newMeasure()
.withValue(value)
.forMetric(metric)
.on(file)
.save();
}catch (Exception e){
LOG.error(e.getMessage());
}
context.<T>newMeasure()
.withValue(value)
.forMetric(metric)
.on(file)
.save();
}
}

@ -6,7 +6,6 @@
*/
package com.keyware.sonar.cxx;
import com.keyware.sonar.cxx.rules.SecurityDesignRuleRepository;
import com.keyware.sonar.cxx.rules.checkers.FlagLineRule;
import com.keyware.sonar.cxx.rules.checkers.SqlVarNameChecker;
import org.sonar.api.batch.fs.FilePredicates;
@ -22,18 +21,18 @@ public class FlagLineSensor implements Sensor {
public FlagLineSensor(CheckFactory checkFactory) {
checks = checkFactory.create(SecurityDesignRuleRepository.REPOSITORY_SQL_KEY);
checks = checkFactory.create("cxx-security-design-rules");
checks.addAnnotatedChecks(SqlVarNameChecker.class);
}
@Override
public void describe(SensorDescriptor descriptor) {
//传感器名称
descriptor.name("FlagLine1RuleSensor");
descriptor.name("FlagLine1Rule" + "sensor");
//传感器识别的语言
descriptor.onlyOnLanguages(CxxLanguage.KEY);
//传感器扫描的规则库
descriptor.createIssuesForRuleRepository(SecurityDesignRuleRepository.REPOSITORY_SQL_KEY);
descriptor.createIssuesForRuleRepository("cxx-security-design-rules");
}
@Override

@ -23,19 +23,17 @@ 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_SQL_KEY = "sql-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,BufferDataChecker.class, CmdDataVerifyChecker.class,
DLLVerifyChecker.class,EncryptionAlgorithmChecker.class,ErrorMessageChecker.class,
FileAccessChecker.class,FormatFunctionCheck.class,FVNRPassWordChecker.class,FVNRShaChecker.class,HighEncryptDesChecker.class,
HostIdentityVerifyChecker.class,IntegerCountVerifyChecker.class,LogFileWriteChecker.class,NumericalCopyChecker.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) {
var repository = context.createRepository(REPOSITORY_KEY, CxxLanguage.KEY).
@ -43,14 +41,9 @@ public class SecurityDesignRuleRepository implements RulesDefinition {
new AnnotationBasedRulesDefinition(repository, CxxLanguage.KEY).addRuleClasses(false, RULE_CHECKERS);
repository.done();
var repository1 = context.createRepository(REPOSITORY_LOG_KEY, LogLanguage.KEY).
var repository1 = context.createRepository(REPOSITORY_log_key, LogLanguage.KEY).
setName(REPOSITORY_NAME);
new AnnotationBasedRulesDefinition(repository1, LogLanguage.KEY).addRuleClasses(false, List.of(LogChecker.class));
new AnnotationBasedRulesDefinition(repository1, LogLanguage.KEY).addRuleClasses(false, RULE_CHECKERS);
repository1.done();
var repository2 = context.createRepository(REPOSITORY_SQL_KEY, CxxLanguage.KEY).
setName(REPOSITORY_NAME);
new AnnotationBasedRulesDefinition(repository2, CxxLanguage.KEY).addRuleClasses(false, List.of(SqlVarNameChecker.class));
repository2.done();
}
}

@ -22,7 +22,7 @@ public class SecurityDesignWayProfile implements BuiltInQualityProfilesDefinitio
@Override
public void define(Context context) {
var way = context.createBuiltInQualityProfile("C++信息安全性设计准则", CxxLanguage.KEY);
//way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "ABCVarNameChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "ABCVarNameChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "BufferDataChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "CmdDataVerifyChecker");
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "DLLVerifyChecker");
@ -42,6 +42,7 @@ public class SecurityDesignWayProfile implements BuiltInQualityProfilesDefinitio
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");
@ -49,8 +50,8 @@ public class SecurityDesignWayProfile implements BuiltInQualityProfilesDefinitio
way.activateRule(SecurityDesignRuleRepository.REPOSITORY_KEY, "VirtualLockUsageChecker");
way.done();
var way1 = context.createBuiltInQualityProfile("log信息安全性设计准则", LogLanguage.KEY);
way1.activateRule(SecurityDesignRuleRepository.REPOSITORY_LOG_KEY, "LogChecker");
var way1 = context.createBuiltInQualityProfile("LogLanguage信息安全性设计准则", LogLanguage.KEY);
way1.activateRule(SecurityDesignRuleRepository.REPOSITORY_log_key, "LogChecker");
way1.done();
}
}

@ -92,7 +92,7 @@ public class BufferDataChecker extends SquidCheck<Grammar> {
for (AstNode ast:descendants) {
String name = ast.getParent().getToken().getValue();
//判断是否时使用sanitizeString方法
if("memcpy".equals(name) || "strncpy".equals(name) || "memset".equals(name) || "strcpy".equals(name)){
if("memcpy".equals(name) || "strncpy".equals(name) || "memset".equals(name)){
//判断方法参数是否进行校验
List<AstNode> astNodeList = ast.getDescendants(CxxGrammarImpl.initializerList);
AstNode astNode = astNodeList.get(astNodeList.size() - 1);
@ -101,20 +101,6 @@ public class BufferDataChecker extends SquidCheck<Grammar> {
if(!lists.contains(tokenValue)){
reportIssue(ast, "应对读写缓冲区的数据长度进行检查");
}
}else if("scanf".equals(name)){
List<AstNode> astNodeList = ast.getDescendants(CxxGrammarImpl.initializerList);
if(astNodeList != null){
AstNode astNode = astNodeList.get(astNodeList.size() - 1);
List<AstNode> childrens = astNode.getChildren();
if(childrens.size() != 0){
String tokenValue = childrens.get(0).getTokenValue();
boolean boo = tokenValue.chars().anyMatch(Character::isDigit);
if(!boo){
reportIssue(ast, "应对读写缓冲区的数据长度进行检查");
}
}
}
}
}
}

@ -72,13 +72,12 @@ public class CmdDataVerifyChecker extends SquidCheck<Grammar> {
//判断节点是不是if节点
if("if".equals(astNode.getToken().getValue())){
//获取其中的参数
List<AstNode> descendants = astNode.getDescendants(CxxGrammarImpl.condition);
// List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList);
// astNodeList.addAll(astNode.getDescendants(CxxGrammarImpl.condition));
for (AstNode expr:descendants) {
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList);
astNodeList.addAll(astNode.getDescendants(CxxGrammarImpl.condition));
for (AstNode expr:astNodeList) {
lists.add(expr.getToken().getValue());
}
if(descendants.size() == 0){
if(astNodeList.size() == 0){
List<AstNode> astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression);
for (AstNode as:astNodes) {
List<AstNode> children = as.getChildren();
@ -95,7 +94,6 @@ public class CmdDataVerifyChecker extends SquidCheck<Grammar> {
String name = ast.getParent().getToken().getValue();
//判断是否时使用sanitizeString方法
if("system".equals(name)){
String valueName = ast.getToken().getValue();
//判断方法参数是否进行校验
if(!lists.contains(ast.getToken().getValue())){
reportIssue(ast, "在构建命令前对输入数据进行验证");

@ -32,7 +32,6 @@ import java.util.Map;
public class DLLVerifyChecker extends SquidCheck<Grammar> {
private static String name = "在动态加载库前对输入数据进行验证";
@Override
public void init() {
// 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点
@ -49,86 +48,101 @@ public class DLLVerifyChecker extends SquidCheck<Grammar> {
@Override
public void visitNode(@Nonnull AstNode node) {
Map<String, Integer> map = ifParam(node);
List<AstNode> descendants = node.getDescendants(CxxGrammarImpl.postfixExpression);
for (AstNode desc :descendants){
if("dlopen".equals(desc.getTokenValue())){
loadParam(map,desc);
}else if ("LoadLibrary".equals(desc.getTokenValue())){
openParam(map,desc);
List<AstNode> simps = node.getDescendants(CxxGrammarImpl.simpleDeclaration);
for(AstNode simp :simps){
//判断动态加载库类型
if("HINSTANCE".equals(simp.getTokenValue())){
loadParam(map,simp);
}else if ("void".equals(simp.getTokenValue())){
openParam(map,simp);
}
}
}
//判断是否是dlopen格式的动态加载库
public void openParam(Map<String, Integer> map, AstNode simp) {
//获取其中的参数列表
AstNode firstDescendant = simp.getFirstDescendant(CxxGrammarImpl.expressionList);
if (firstDescendant != null) {
List<AstNode> children = firstDescendant.getChildren();
for (AstNode dren : children) {
//获取参数并进行判断是否是传入的参数
if ("IDENTIFIER".equals(dren.getName()) || "initializerList".equals(dren.getName())) {
if (map.containsKey(dren.getTokenValue())) {
//判断参数是否进行过校验
Integer integer = map.get(dren.getTokenValue());
//判断参数校验是否在使用之前
if (dren.getTokenLine() < integer) {
getContext().createLineViolation(this, name, dren);
public void openParam(Map<String,Integer> map,AstNode simp){
//获取方法名
List<AstNode> descendants = simp.getDescendants(CxxGrammarImpl.postfixExpression);
if(descendants != null){
for(AstNode desc : descendants){
//判断是否式动态加载库
if("dlopen".equals(desc.getTokenValue())){
//获取其中的参数列表
AstNode firstDescendant = desc.getFirstDescendant(CxxGrammarImpl.expressionList);
if(firstDescendant != null){
List<AstNode> children = firstDescendant.getChildren();
for(AstNode dren : children){
//获取参数并进行判断是否是传入的参数
if("IDENTIFIER".equals(dren.getName()) || "initializerList".equals(dren.getName())){
if(map.containsKey(dren.getTokenValue())){
//判断参数是否进行过校验
Integer integer = map.get(dren.getTokenValue());
//判断参数校验是否在使用之前
if(dren.getTokenLine() < integer){
getContext().createLineViolation(this,name,dren);
}
}else {
getContext().createLineViolation(this,name,dren);
}
}
}
} else {
getContext().createLineViolation(this, name, dren);
}
}
}
}
}
//对LoadLibrary格式的动态加载库进行校验
public void loadParam(Map<String, Integer> map, AstNode simp) {
List<AstNode> descendants = simp.getDescendants(CxxGrammarImpl.expressionList);
if (descendants != null) {
for (AstNode desc : descendants) {
//判断参数是否进行过校验
if (map.containsKey(desc.getTokenValue())) {
//判断参数校验是否在使用之前
int tokenLine = map.get(desc.getTokenValue());
if (desc.getTokenLine() < tokenLine) {
getContext().createLineViolation(this, name, desc);
break;
public void loadParam(Map<String,Integer> map,AstNode simp){
//获取方法名
AstNode firstDescendant = simp.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if(firstDescendant != null){
if("LoadLibrary".equals(firstDescendant.getTokenValue())){
//获取其中的参数列表
List<AstNode> descendants = firstDescendant.getDescendants(CxxGrammarImpl.expressionList);
if(descendants != null){
for (AstNode desc : descendants){
//判断参数是否进行过校验
if (map.containsKey(desc.getTokenValue())){
//判断参数校验是否在使用之前
int tokenLine = map.get(desc.getTokenValue());
if(desc.getTokenLine() < tokenLine){
getContext().createLineViolation(this,name,desc);
break;
}
}else {
getContext().createLineViolation(this,name,desc);
break;
}
}
} else {
getContext().createLineViolation(this, name, desc);
break;
}else {
getContext().createLineViolation(this,name,firstDescendant);
}
}
} else {
getContext().createLineViolation(this, name, simp);
}
}
//获取if判断中的参数
public static Map<String, Integer> ifParam(AstNode node) {
public static Map<String, Integer> ifParam(AstNode node){
Map<String, Integer> map = new HashMap<>();
//选择节点语句
List<AstNode> nodeDescendants = node.getDescendants(CxxGrammarImpl.selectionStatement);
for (AstNode astNode : nodeDescendants) {
for (AstNode astNode:nodeDescendants) {
//判断节点是不是if节点
if ("if".equals(astNode.getToken().getValue())) {
if("if".equals(astNode.getToken().getValue())){
//获取其中的参数
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList);
astNodeList.addAll(astNode.getDescendants(CxxGrammarImpl.condition));
for (AstNode expr : astNodeList) {
map.put(expr.getTokenValue(), expr.getTokenLine());
for (AstNode expr:astNodeList) {
map.put(expr.getTokenValue(),expr.getTokenLine());
}
//判断第二种情况获取到if里面的参数
if (astNodeList.size() == 0) {
if(astNodeList.size() == 0){
List<AstNode> astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression);
for (AstNode as : astNodes) {
for (AstNode as:astNodes) {
List<AstNode> children = as.getChildren();
for (AstNode chil : children) {
map.put(chil.getTokenValue(), chil.getTokenLine());
for (AstNode chil:children) {
map.put(chil.getTokenValue(),chil.getTokenLine());
}
}
}

@ -43,37 +43,30 @@ public class EncryptionAlgorithmChecker extends SquidCheck<Grammar> {
@Override
public void visitNode(AstNode astNode) {
AstNode descendant = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId);
if(descendant != null){
var varName =descendant.getTokenValue();
if(varName.contains("password") && !cache.containsKey(varName)){
cache.put(varName, astNode);
var next = astNode.getNextAstNode();
while (next != null){
var callNode = next.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if(callNode != null){
var callList = callNode.getDescendants(CxxGrammarImpl.className);
if(callList != null && !callList.isEmpty()) {
var funName = callList.get(callList.size() - 1).getTokenValue();
var paramList = callNode.getDescendants(CxxGrammarImpl.expressionList);
if("hashpw".equalsIgnoreCase(funName) && paramList.stream().anyMatch(item-> {
var name = item.getTokenValue();
return name != null && ("password".equals(name) || "salt".equals(name));
})){
cache.remove(varName);
}
var varName = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId).getTokenOriginalValue();
if(varName.contains("password") && !cache.containsKey(varName)){
cache.put(varName, astNode);
var next = astNode.getNextAstNode();
while (next != null){
var callNode = next.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if(callNode != null){
var callList = callNode.getDescendants(CxxGrammarImpl.className);
if(!callList.isEmpty()) {
var funName = callList.get(callList.size() - 1).getTokenOriginalValue();
var paramList = callNode.getDescendants(CxxGrammarImpl.expressionList);
if("hashpw".equalsIgnoreCase(funName) && paramList.stream().anyMatch(item-> {
var name = item.getTokenOriginalValue();
return name != null && ("password".equals(name) || "salt".equals(name));
})){
cache.remove(varName);
}
}
next = next.getNextSibling();
}
cache.values().forEach(item->{
getContext().createLineViolation(this, "特定字段未使用单向加密算法对口令进行加密并存储", item);
});
}else if(astNode.getTokenValue().contains("AESEncryption") ){
getContext().createLineViolation(this, "特定字段未使用单向加密算法对口令进行加密并存储", astNode);
next = next.getNextSibling();
}
cache.values().forEach(item->{
getContext().createLineViolation(this, "特定字段未使用单向加密算法对口令进行加密并存储", item);
});
}
String tokenValue = astNode.getTokenValue();
}
}

@ -53,35 +53,26 @@ public class ErrorMessageChecker extends SquidCheck<Grammar> {
*/
@Override
public void visitNode(@Nonnull AstNode node) {
//声明集合
List<AstNode> children;
//获取第一种情况参数列表
AstNode firstDescendant = node.getFirstDescendant(CxxGrammarImpl.additiveExpression);
if(firstDescendant != null){
//第一种情况获取参数列表
List<AstNode> children = firstDescendant.getChildren();
//判断参数列表是否包含违规参数
for(AstNode chil : children){
if("IDENTIFIER".equals(chil.getName())){
if(lists.contains(chil.getTokenValue().toLowerCase())){
getContext().createLineViolation(this,"抛出异常消息不得包含敏感信息",chil);
}
}
}
children = firstDescendant.getChildren();
}else {
//获取第二种情况获取参数列表
AstNode descendant = node.getFirstDescendant(CxxGrammarImpl.initializerList);
if(descendant != null){
List<AstNode> children = descendant.getChildren();
for(AstNode chil : children){
if("IDENTIFIER".equals(chil.getName())){
if(lists.contains(chil.getTokenValue().toLowerCase())){
getContext().createLineViolation(this,"抛出异常消息不得包含敏感信息",chil);
}
}
children = descendant.getChildren();
}
//判断参数列表是否包含违规参数
for(AstNode chil : children){
if("IDENTIFIER".equals(chil.getName())){
if(lists.contains(chil.getTokenValue().toLowerCase())){
getContext().createLineViolation(this,"抛出异常消息不得包含敏感信息",chil);
}
}
}
}
}

@ -43,7 +43,7 @@ public class FVNRPassWordChecker extends SquidCheck<Grammar> {
List<String> inputFileLines = getContext().getInputFileLines();
for (String str:inputFileLines) {
if(str.startsWith("#include")){
if(str.contains("openssl/aes.h") || str.contains("openssl/des.h") || str.contains("\"aes.h\"")){
if(str.contains("openssl/aes.h") || str.contains("openssl/des.h")){
getContext().createFileViolation(this, "应使用单向不可逆算法对密码进行加密");
break;
}

@ -41,13 +41,14 @@ public class FVNRShaChecker extends SquidCheck<Grammar> {
public void visitFile(@Nullable AstNode astNode) {
//逐行获取内容
List<String> inputFileLines = getContext().getInputFileLines();
for (String str : inputFileLines) {
if (str.startsWith("#include")) {
if (!str.contains("sha.h") && !str.contains("blake2.h") && !str.contains("md5.h")) {
getContext().createFileViolation(this, "应使用不可逆标准散列算法");
break;
for (String str:inputFileLines) {
if(str.startsWith("#include")){
if(str.contains("openssl/") || str.contains("cryptopp/") ){
if(!str.contains("sha.h") && !str.contains("blake2.h") && !str.contains("md5.h")){
getContext().createFileViolation(this, "应使用不可逆标准散列算法");
break;
}
}
}
}
}

@ -6,9 +6,7 @@
*/
package com.keyware.sonar.cxx.rules.checkers;
import com.sonar.cxx.sslr.api.AstNode;
import com.sonar.cxx.sslr.api.GenericTokenType;
import com.sonar.cxx.sslr.api.Grammar;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
@ -17,10 +15,6 @@ import org.sonar.cxx.squidbridge.annotations.ActivatedByDefault;
import org.sonar.cxx.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.cxx.squidbridge.checks.SquidCheck;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 在访问文件或目录前对路径名进行验证
@ -33,106 +27,68 @@ import java.util.Set;
@ActivatedByDefault
@SqaleConstantRemediation("5min")
public class FileAccessChecker extends SquidCheck<Grammar> {
private Set<String> conditionVariables;
private boolean filePathChecked = false;
private boolean filePathUsedInIf = false;
@Override
public void init() {
subscribeTo(CxxGrammarImpl.selectionStatement);
subscribeTo(CxxGrammarImpl.declaration);
subscribeTo(CxxGrammarImpl.postfixExpression);
conditionVariables = new HashSet<>();
subscribeTo(CxxGrammarImpl.selectionStatement, CxxGrammarImpl.declaration, CxxGrammarImpl.statement);
}
@Override
public void visitNode(AstNode node) {
if (node.is(CxxGrammarImpl.selectionStatement)) {
handleIfStatement(node);
} else if (node.is(CxxGrammarImpl.declaration)) {
addAllIdentifiers(node);
handleDeclaration(node);
} else if (node.is(CxxGrammarImpl.postfixExpression)) {
verdictExpression(node);
}
}
private void verdictExpression(AstNode node) {
String methodName = node.getTokenValue();
if (methodName != null) {
if ("fopen".equals(methodName)) {
List<AstNode> descendants = node.getDescendants(CxxGrammarImpl.expressionList);
if(descendants != null){
for(AstNode desc : descendants){
String name = desc.getTokenValue();
if (!conditionVariables.contains(name)) {
getContext().createLineViolation(this, "在访问文件或目录前需要对路径名进行验证", node);
}
}
}
}
public void visitNode(AstNode astNode) {
if (astNode.is(CxxGrammarImpl.selectionStatement)) {
checkIfStatement(astNode);
} else if (astNode.is(CxxGrammarImpl.declaration)) {
checkDeclaration(astNode);
} else if (astNode.is(CxxGrammarImpl.statement)) {
checkStatement(astNode);
}
}
private void handleDeclaration(AstNode node) {
AstNode ifstreamNode = findIfstreamNode(node);
if (ifstreamNode != null) {
handleIfstreamDeclaration(ifstreamNode);
private void checkIfStatement(AstNode ifStatement) {
AstNode condition = ifStatement.getFirstChild(CxxGrammarImpl.condition);
filePathUsedInIf = containsFilePathCheck(condition);
if (!filePathUsedInIf) {
createViolation(ifStatement, "在访问文件或目录前需要对路径名进行验证");
}
filePathUsedInIf = false;
}
private AstNode findIfstreamNode(AstNode node) {
if (node.getToken() != null && "ifstream".equals(node.getTokenValue())) {
return node;
}
for (AstNode child : node.getChildren()) {
AstNode result = findIfstreamNode(child);
if (result != null) {
return result;
private void checkDeclaration(AstNode declaration) {
AstNode declaratorNode = declaration.getFirstDescendant(CxxGrammarImpl.declarator);
filePathChecked = containsFilePathCheck(declaratorNode);
if (declaratorNode != null && !filePathChecked) {
String variableName = declaratorNode.getTokenOriginalValue();
if (variableName != null && variableName.equals("filePath")) {
System.out.println(variableName);
getContext().createLineViolation(this, "在访问文件或目录前需要对路径名进行验证", declaratorNode);
}
}
return null;
}
private void handleIfStatement(AstNode node) {
AstNode conditionNode = node.getFirstDescendant(CxxGrammarImpl.condition);
if (conditionNode != null) {
addAllIdentifiers(conditionNode);
}
private void checkStatement(AstNode statement) {
AstNode condition = statement.getFirstChild(CxxGrammarImpl.condition);
filePathChecked = containsFilePathCheck(condition);
}
private void addAllIdentifiers(AstNode node) {
for (AstNode child : node.getChildren()) {
if (child.getType().equals(CxxGrammarImpl.selectionStatement)) {
// 找到 if 语句节点
AstNode conditionNode = child.getFirstDescendant(CxxGrammarImpl.condition);
if(conditionNode != null){
// 找到条件部分的节点
AstNode identifierNode = conditionNode.getFirstDescendant(GenericTokenType.IDENTIFIER);
// 找到代表标识符的节点
if (identifierNode != null) {
String codeInsideIf = identifierNode.getTokenValue();
// 获取标识符节点的值
conditionVariables.add(codeInsideIf);
}
private boolean containsFilePathCheck(AstNode node) {
if (node != null && node.getTokenOriginalValue().equals("filePath")) {
return true;
}
if (node != null) {
for (AstNode child : node.getChildren()) {
// 如果 if 中使用了 filePath,则停止递归并跳过 ifstream file(filePath) 检查
if (containsFilePathCheck(child)) {
return true;
}
} else {
addAllIdentifiers(child);
}
}
return false; // 节点或其任何子节点中找不到“filePath”
}
private void handleIfstreamDeclaration(AstNode ifstreamNode) {
AstNode parameterDeclarationNode = ifstreamNode.getFirstDescendant(CxxGrammarImpl.parameterDeclaration);
if (parameterDeclarationNode != null) {
AstNode identifierNode = parameterDeclarationNode.getFirstDescendant(GenericTokenType.IDENTIFIER);
if (identifierNode != null) {
String ifstreamParam = identifierNode.getTokenValue();
if (!conditionVariables.contains(ifstreamParam)) {
getContext().createLineViolation(this, "在访问文件或目录前需要对路径名进行验证", ifstreamNode);
}
}
}
private void createViolation(AstNode node, String message) {
getContext().createLineViolation(this, message, node);
}
}

@ -41,11 +41,13 @@ public class HighEncryptDesChecker extends SquidCheck<Grammar> {
public void visitFile(@Nullable AstNode astNode) {
//逐行获取内容
List<String> inputFileLines = getContext().getInputFileLines();
for (String str : inputFileLines) {
if (str.startsWith("#include")) {
if (str.contains("des.h") || str.contains("blake2.h")) {
getContext().createFileViolation(this, "应采用加密强度较高的标准加密算法");
break;
for (String str:inputFileLines) {
if(str.startsWith("#include")){
if(str.contains("openssl/") || str.contains("cryptopp/") ){
if(!str.contains("aes.h") && !str.contains("des.h") ){
getContext().createFileViolation(this, "应采用加密强度较高的标准加密算法");
break;
}
}
}
}

@ -96,39 +96,23 @@ public class IntegerCountVerifyChecker extends SquidCheck<Grammar> {
}else if("std".equals(stList.getTokenValue())){
//获取到方法名称
AstNode firstDescendant = stList.getFirstDescendant(CxxGrammarImpl.qualifiedId);
if (firstDescendant!=null){
List<AstNode> children = firstDescendant.getChildren();
for(AstNode desc : children){
//判断是否是用户输入方法
if("cin".equals(desc.getTokenValue())){
//获取用户输入中的参数变量
AstNode descendant = stList.getFirstDescendant(CxxGrammarImpl.shiftExpression);
if (descendant!=null){
List<AstNode> descendantChildren = descendant.getChildren();
for(AstNode dant:descendantChildren){
if("IDENTIFIER".equals(dant.getName())){
//判断输入的是否是整形变量
if(lists.contains(dant.getTokenValue())){
cinList.add(dant.getTokenValue());
}
}
List<AstNode> children = firstDescendant.getChildren();
for(AstNode desc : children){
//判断是否是用户输入方法
if("cin".equals(desc.getTokenValue())){
//获取用户输入中的参数变量
AstNode descendant = stList.getFirstDescendant(CxxGrammarImpl.shiftExpression);
List<AstNode> descendantChildren = descendant.getChildren();
for(AstNode dant:descendantChildren){
if("IDENTIFIER".equals(dant.getName())){
//判断输入的是否是整形变量
if(lists.contains(dant.getTokenValue())){
cinList.add(dant.getTokenValue());
}
}
}
}
}
}else {
List<AstNode> descendants = stList.getDescendants(CxxGrammarImpl.declSpecifier);
AstNode descendant = stList.getFirstDescendant(CxxGrammarImpl.postfixExpression);
AstNode declName = stList.getFirstDescendant(CxxGrammarImpl.declarator);
if(descendants != null && descendant != null && declName != null){
for(AstNode desc : descendants){
if(desc.getTokenValue().contains("int") ){
cinList.add(declName.getTokenValue());
break;
}
}
}
}
}
return cinList;

@ -90,42 +90,36 @@ public class LogFileWriteChecker extends SquidCheck<Grammar> {
tokenValue = descendant.getTokenValue();
} else {
AstNode firstDescendant = dec.getFirstDescendant(CxxGrammarImpl.andExpression);
if(firstDescendant != null){
List<AstNode> astNodeList = firstDescendant.getChildren();
for (AstNode ast : astNodeList) {
if ("IDENTIFIER".equals(ast.getName())) {
tokenValue = ast.getTokenValue();
}
List<AstNode> astNodeList = firstDescendant.getChildren();
for (AstNode ast : astNodeList) {
if ("IDENTIFIER".equals(ast.getName())) {
tokenValue = ast.getTokenValue();
}
}
}
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expression);
for (AstNode ast : astNodeList) {
if (tokenValue.equals(ast.getTokenValue())) {
AstNode descendant1 = ast.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if(descendant1 != null){
List<AstNode> childrens = descendant1.getChildren();
for (AstNode fir : childrens) {
//判断是否是debug、info、warn、error
if (lists.contains(fir.getTokenValue())) {
AstNode inits = ast.getFirstDescendant(CxxGrammarImpl.initializerList);
if(inits != null){
List<AstNode> descendantChildren = inits.getChildren();
for (AstNode chil : descendantChildren) {
if ("IDENTIFIER".equals(chil.getName())) {
if (listss.contains(chil.getTokenValue().toLowerCase())) {
getContext().createLineViolation(this, "慎重考虑写入日志文件信息的隐私性", chil);
break;
}
} else if ("additiveExpression".equals(chil.getName())) {
List<AstNode> chilChildren = chil.getChildren();
for (AstNode dren : chilChildren) {
if (listss.contains(dren.getTokenValue().toLowerCase())) {
getContext().createLineViolation(this, "慎重考虑写入日志文件信息的隐私性", dren);
break;
}
}
List<AstNode> childrens = descendant1.getChildren();
for (AstNode fir : childrens) {
//判断是否是debug、info、warn、error
if (lists.contains(fir.getTokenValue())) {
AstNode inits = ast.getFirstDescendant(CxxGrammarImpl.initializerList);
List<AstNode> descendantChildren = inits.getChildren();
for (AstNode chil : descendantChildren) {
if ("IDENTIFIER".equals(chil.getName())) {
if (listss.contains(chil.getTokenValue().toLowerCase())) {
getContext().createLineViolation(this, "慎重考虑写入日志文件信息的隐私性", chil);
break;
}
} else if ("additiveExpression".equals(chil.getName())) {
List<AstNode> chilChildren = chil.getChildren();
for (AstNode dren : chilChildren) {
if (listss.contains(dren.getTokenValue().toLowerCase())) {
getContext().createLineViolation(this, "慎重考虑写入日志文件信息的隐私性", dren);
break;
}
}
}

@ -26,32 +26,33 @@ public class NumericalCopyChecker extends SquidCheck<Grammar> {//当私有数组
public void init() {
// 订阅要检查AST节点类型,用于在visitNode方法中检查该类型节点
this.subscribeTo(
CxxGrammarImpl.translationUnit
CxxGrammarImpl.functionDefinition
);
}
public void visitNode(AstNode astNode) {
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.declarator);
List<String> lists = new ArrayList();
for (AstNode desc : astNodeList) {
if (desc.getTokenValue().contains("private")) {
lists.add(desc.getTokenValue());
}
}
for (AstNode as : astNodeList) {
if (as.getTokenValue().contains("&") || as.getTokenValue().contains("*")) {
List<String> lists = new ArrayList();
List<AstNode> descendant = astNode.getDescendants(CxxGrammarImpl.expression);
for (AstNode desc : descendant) {
lists.add(desc.getTokenValue());
}
List<AstNode> descendan = astNode.getDescendants(CxxGrammarImpl.statement);
for (AstNode ast : descendan) {
List<AstNode> descendants = ast.getDescendants(CxxGrammarImpl.expression);
for (AstNode des : descendants) {
if ("return".equals(des.getParent().getTokenValue())) {
if (lists.contains(des.getTokenValue())) {
getContext().createLineViolation(this, "应返回该私有数值的副本", des);
}
if (lists.contains(des.getTokenValue())) {
getContext().createLineViolation(this, "应返回该私有数值的副本", des);
}
}
}
}
}
}
}

@ -33,12 +33,9 @@ public class PRNGVerifyChecker extends SquidCheck<Grammar> {
@Override
public void init() {
// 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点
subscribeTo(
this.subscribeTo(
CxxGrammarImpl.declarationStatement
);
subscribeTo(
CxxGrammarImpl.postfixExpression
);
}
/**
@ -48,20 +45,13 @@ public class PRNGVerifyChecker extends SquidCheck<Grammar> {
*/
@Override
public void visitNode(@Nonnull AstNode node) {
if(node.is(CxxGrammarImpl.postfixExpression)){
if(node.getTokenValue().contains("rand")){
List<AstNode> descendants = node.getDescendants(CxxGrammarImpl.typeName);
for (AstNode desc:descendants) {
if(lists.contains(desc.getTokenValue())){
getContext().createLineViolation(this, "应使用目前被业界专家认为较强的经过良好审核的加密PRNG算法", node);
}
}else if(node.is(CxxGrammarImpl.declarationStatement)){
List<AstNode> descendants = node.getDescendants(CxxGrammarImpl.typeName);
for (AstNode desc:descendants) {
if(lists.contains(desc.getTokenValue())){
getContext().createLineViolation(this, "应使用目前被业界专家认为较强的经过良好审核的加密PRNG算法", node);
break;
}
break;
}
}
}
}

@ -17,7 +17,6 @@ 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.ArrayList;
import java.util.List;
@ -47,12 +46,12 @@ public class PassWordCountChecker extends SquidCheck<Grammar> {
* @param astNode 要处理的AST节点该节点类型为通过subscribeTo方法订阅的类型
*/
@Override
public void visitNode(@Nonnull AstNode astNode) {
public void visitNode(AstNode astNode) {
BodyWay bodyWay = new BodyWay(this);
bodyWay.accept(astNode);
}
class BodyWay extends SubscriptionAstVisitor {
class BodyWay extends SubscriptionAstVisitor{
/**
* 构造函数需要传入初代访问器
@ -73,78 +72,45 @@ public class PassWordCountChecker extends SquidCheck<Grammar> {
//获取方法参数列表
List<AstNode> nodeDescendants = astNode.getDescendants(CxxGrammarImpl.expressionList);
List<String> seqLists = new ArrayList<>();
for (AstNode desc : nodeDescendants) {
for(AstNode desc :nodeDescendants){
seqLists.add(desc.getTokenValue());
}
//判读入参有没有进行赋值操作
List<AstNode> astNodes = astNode.getDescendants(CxxGrammarImpl.assignmentExpression);
List<String> aslists = new ArrayList<>();
for (AstNode ast : astNodes) {
if (seqLists.contains(ast.getTokenValue())) {
for(AstNode ast : astNodes){
if(seqLists.contains(ast.getTokenValue())){
aslists.add(ast.getTokenValue());
}
}
//获取到声明hash变量名
List<String> lists = new ArrayList<>();
List<AstNode> astNodeDescendants = astNode.getDescendants(CxxGrammarImpl.simpleDeclaration);
for (AstNode des : astNodeDescendants) {
List<AstNode> descendants = des.getDescendants(CxxGrammarImpl.typeName);
for (AstNode dan : descendants) {
if ("hash".equals(dan.getTokenValue())) {
List<AstNode> nodeList = des.getDescendants(CxxGrammarImpl.initDeclarator);
for (AstNode lis : nodeList) {
lists.add(lis.getTokenValue());
for(AstNode des :astNodeDescendants){
if("std".equals(des.getTokenValue())){
List<AstNode> descendants = des.getDescendants(CxxGrammarImpl.typeName);
for (AstNode dan : descendants){
if("hash".equals(dan.getTokenValue())){
List<AstNode> nodeList = des.getDescendants(CxxGrammarImpl.initDeclarator);
for (AstNode lis:nodeList) {
lists.add(lis.getTokenValue());
}
}
}
}
}
//判断生成的散列值参数是否是进行赋后的入参
List<AstNode> descendants = astNode.getDescendants(CxxGrammarImpl.postfixExpression);
for (AstNode desc : descendants) {
if (lists.contains(desc.getTokenValue())) {
for (AstNode desc:descendants) {
if(lists.contains(desc.getTokenValue())){
List<AstNode> descDescendants = desc.getDescendants(CxxGrammarImpl.expressionList);
for (AstNode dd : descDescendants) {
if (!aslists.contains(dd.getTokenValue())) {
for(AstNode dd : descDescendants){
if(!aslists.contains(dd.getTokenValue())){
reportIssue(dd, "使用盐值计算散列值");
}
}
}
}
List arrLists = new ArrayList();
//获取数组
List<AstNode> nodeList = astNode.getDescendants(CxxGrammarImpl.initDeclaratorList);
for(AstNode node : nodeList){
AstNode firstDescendant = node.getFirstDescendant(CxxGrammarImpl.constantExpression);
if(firstDescendant != null){
if(firstDescendant.getTokenValue().contains("SHA256_DIGEST_LENGTH")){
aslists.add(node.getTokenValue());
}
}
}
List<AstNode> nodes = astNode.getDescendants(CxxGrammarImpl.postfixExpression);
for(AstNode node : nodes){
String methodName = node.getTokenValue();
if (methodName.contains("hash") || methodName.contains("encryptor")) {
AstNode init = node.getFirstDescendant(CxxGrammarImpl.initializerList);
boolean booPassword = false;
boolean booHash = true;
if(init != null){
List<AstNode> children = init.getChildren();
for(AstNode child : children){
if(child.getTokenValue().toLowerCase().contains("password")){
booPassword = true;
}else if(arrLists.contains(child.getTokenValue())){
booHash = false;
}
}
}
if(booHash && booPassword){
reportIssue(init, "使用盐值计算散列值");
}
}
}
}
}
}

@ -6,9 +6,7 @@
*/
package com.keyware.sonar.cxx.rules.checkers;
import com.keyware.sonar.cxx.SubscriptionAstVisitor;
import com.sonar.cxx.sslr.api.AstNode;
import com.sonar.cxx.sslr.api.AstNodeType;
import com.sonar.cxx.sslr.api.Grammar;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
@ -18,7 +16,6 @@ import org.sonar.cxx.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.cxx.squidbridge.checks.SquidCheck;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -40,7 +37,7 @@ public class PathVerifyChecker extends SquidCheck<Grammar> {
public void init() {
// 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点
this.subscribeTo(
CxxGrammarImpl.functionBody
CxxGrammarImpl.declarationStatement
);
}
@ -51,9 +48,21 @@ public class PathVerifyChecker extends SquidCheck<Grammar> {
*/
@Override
public void visitNode(@Nonnull AstNode node) {
IfBuffer ifBuffer = new IfBuffer(this);
ifBuffer.accept(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);
}
}
}
}
}
//判断是不是路径
@ -80,84 +89,4 @@ public class PathVerifyChecker extends SquidCheck<Grammar> {
return matcher.find(); // 使用find()而不是matches(),因为matches()要求整个字符串都符合模式
}
class IfBuffer extends SubscriptionAstVisitor {
List lists = new ArrayList<String>();
public IfBuffer(SquidCheck<Grammar> checker) {
super(checker);
}
@Override
public List<AstNodeType> visitNodeTypes() {
// 指定当前访问器需要访问的节点类型,这里指定了simpleDeclaration(简单声明)节点类型
return List.of(CxxGrammarImpl.functionBody);
}
@Override
public void visitNode(@Nonnull AstNode node) {
//选择节点语句
List<AstNode> nodeDescendants = node.getDescendants(CxxGrammarImpl.selectionStatement);
for (AstNode astNode : nodeDescendants) {
//判断节点是不是if节点
if ("if".equals(astNode.getToken().getValue())) {
//获取其中的参数
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList);
for (AstNode expr : astNodeList) {
lists.add(expr.getToken().getValue());
}
if (astNodeList.size() == 0) {
List<AstNode> astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression);
for (AstNode as : astNodes) {
List<AstNode> children = as.getChildren();
for (AstNode chil : children) {
lists.add(chil.getTokenValue());
}
}
}
}
}
List<AstNode> astNodes = node.getDescendants(CxxGrammarImpl.declarationStatement);
if (astNodes !=null && !astNodes.isEmpty()) {
for (AstNode astNode : astNodes) {
//获取参数
AstNode firstDescendant = astNode.getFirstDescendant(CxxGrammarImpl.initializer);
if (firstDescendant != null) {
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)) {
reportIssue(chil, "使用关键资源时指定资源所在的路径");
}
}
}
}
}
}
}
List<AstNode> descendants = node.getDescendants(CxxGrammarImpl.expression);
for (AstNode ast : descendants) {
AstNode descendant = ast.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if (descendant != null) {
String methodName = descendant.getTokenValue();
if ("system".equals(methodName) || "fopen".equals(methodName)) {
List<AstNode> childrens = descendant.getChildren();
if (childrens != null && !childrens.isEmpty()) {
String tokenValue = childrens.get(0).getTokenValue();
if (tokenValue != null && !lists.equals(tokenValue)) {
reportIssue(descendant, "使用关键资源时指定资源所在的路径");
}
}
}
}
}
}
}
}

@ -92,7 +92,7 @@ public class ReallocMainChecker extends SquidCheck<Grammar> {
String name = as.getToken().getValue();
//判断参数是否存在在集合中
if(!lists.contains(name)){
reportIssue(as, "使用realloc函数前应先清敏感信息");
reportIssue(as, "使用realloc函数前应先清敏感信息");
}
}
}

@ -54,7 +54,6 @@ public class SQLVerifyChecker extends SquidCheck<Grammar> {
class IfSQL extends SubscriptionAstVisitor{
List lists = new ArrayList<String>();
List names = new ArrayList<String>();
public IfSQL(SquidCheck<Grammar> checker){
super(checker);
}
@ -100,43 +99,6 @@ public class SQLVerifyChecker extends SquidCheck<Grammar> {
}
}
}
List<AstNode> astNodes = node.getDescendants(CxxGrammarImpl.declarationStatement);
for(AstNode astNode : astNodes){
String tokenValue = astNode.getTokenValue();
if(tokenValue != null && tokenValue.equals("char")){
AstNode descendant = astNode.getFirstDescendant(CxxGrammarImpl.initDeclaratorList);
if(descendant != null && descendant.getTokenValue().contains("sql")){
names.add(descendant.getTokenValue());
}
}
}
List<AstNode> expressions = node.getDescendants(CxxGrammarImpl.expression);
for (AstNode ast : expressions) {
AstNode descendant = ast.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if (descendant != null) {
String methodName = descendant.getTokenValue();
if ("strcat".equals(methodName) ) {
List<AstNode> astNodeList = descendant.getDescendants(CxxGrammarImpl.initializerList);
boolean booValue = false;
for(AstNode astNode : astNodeList){
List<AstNode> childrens = astNode.getChildren();
if (childrens != null && !childrens.isEmpty()) {
for(AstNode chil : childrens){
if(names.contains(chil.getTokenValue()) ){
booValue = true;
}else if(booValue && chil.getName() == "IDENTIFIER"&& !lists.contains(chil.getTokenValue())){
reportIssue(chil, "在使用SQL语句前对输入数据进行验证");
break;
}
}
}
}
}
}
}
}
}
}

@ -36,16 +36,10 @@ public class SendMessageChecker extends SquidCheck<Grammar> {
CxxGrammarImpl.functionBody
);
}
private static List<String> lists = new ArrayList() {{
private static List<String> lists = new ArrayList(){{
add("weapon");
add("unit");
add("param");
add("address");
add("name");
add("password");
add("orgname");
add("armsname");
}};
@ -60,40 +54,20 @@ public class SendMessageChecker extends SquidCheck<Grammar> {
//获取到所有的表达式
List<AstNode> descendants = node.getDescendants(CxxGrammarImpl.expression);
for (AstNode des : descendants) {
for (AstNode des:descendants) {
//判断表达式是否是send发送信息
if ("send".equals(des.getTokenValue())) {
if("send".equals(des.getTokenValue())){
//获取其中的参数
AstNode firstDescendant = des.getFirstDescendant(CxxGrammarImpl.initializerList);
List<AstNode> children = firstDescendant.getChildren();
if (children != null) {
AstNode astNode = children.get(2);
//判断其中的参数类型
if ("STRING".equals(astNode.getName())) {
} else {
//判斷其中是否包含敏感字段
if (lists.contains(astNode.getTokenValue().toLowerCase())) {
getContext().createLineViolation(this, "发送敏感信息前应对敏感信息进行加密", des);
}
}
}
} else if (des.getTokenValue().startsWith("send")) {
//获取其中的参数
AstNode firstDescendant = des.getFirstDescendant(CxxGrammarImpl.initializerList);
if(firstDescendant != null){
List<AstNode> children = firstDescendant.getChildren();
if (children != null) {
AstNode astNode = children.get(0);
//判断其中的参数类型
if ("STRING".equals(astNode.getName())) {
AstNode astNode = children.get(2);
//判断其中的参数类型
if("STRING".equals(astNode.getName())){
} else {
//判斷其中是否包含敏感字段
if (lists.contains(astNode.getTokenValue().toLowerCase())) {
getContext().createLineViolation(this, "发送敏感信息前应对敏感信息进行加密", des);
}
}
}else {
//判斷其中是否包含敏感字段
if(lists.contains(astNode.getTokenValue().toLowerCase())){
getContext().createLineViolation(this,"发送敏感信息前应对敏感信息进行加密",des);
}
}
}

@ -25,7 +25,7 @@ import java.util.Scanner;
* @author GuoXin
* @date 2024/1/6
*/
@Rule(key = "SqlVarNameChecker", name = "sql注入", description = "sql注入有一定风险", priority = Priority.INFO, tags = {"28suo"})
@Rule(key = "FlagLine1Rule", name = "sql注入", description = "sql注入有一定风险", priority = Priority.INFO, tags = {"28suo"})
@ActivatedByDefault
@SqaleConstantRemediation("5min")
public class SqlVarNameChecker implements FlagLineRule {
@ -54,5 +54,25 @@ public class SqlVarNameChecker implements FlagLineRule {
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();
}
}*/
}

@ -17,7 +17,6 @@ import org.sonar.cxx.squidbridge.checks.SquidCheck;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -37,83 +36,51 @@ public class UserInputPasswordChecker extends SquidCheck<Grammar> {
@Override
public void init() {
subscribeTo(CxxGrammarImpl.functionBody);
subscribeTo(CxxGrammarImpl.simpleDeclaration);
}
@Override
public void visitNode(@Nullable AstNode astNode) {
if(astNode.is(CxxGrammarImpl.simpleDeclaration)){
var declNode = astNode.getFirstDescendant(CxxGrammarImpl.declSpecifier);
if (declNode == null) {
return;
}
var declName = declNode.getTokenValue();
if (!"QLineEdit".equals(declName)) {
return;
}
astNode.getFirstDescendant(CxxGrammarImpl.initDeclaratorList).getChildren().forEach(child -> {
var fieldName = child.getFirstDescendant(CxxGrammarImpl.declaratorId).getTokenValue();
if (fieldName.toLowerCase().contains("password")) {
fieldsMap.put(fieldName, child);
// 判断声明节点的下一个节点是否为函数调用节点
var next = astNode.getNextAstNode();
do {
if (fieldName.equals(next.getTokenValue())) {
var nnext = next.getNextAstNode();
if (nnext != null && "setEchoMode".equals(nnext.getTokenValue())) {
var paramNode = nnext.getFirstDescendant(CxxGrammarImpl.parameterDeclarationList);
if (paramNode.hasDescendant(CxxGrammarImpl.qualifiedId)) {
var qualifiedNode = paramNode.getFirstDescendant(CxxGrammarImpl.qualifiedId);
if (qualifiedNode != null) {
if ("QLineEdit".equals(qualifiedNode.getFirstChild().getTokenValue())
&& "Password".equals(qualifiedNode.getLastChild().getTokenValue())) {
fieldsMap.remove(fieldName);
}
public void visitNode(AstNode astNode) {
var declNode = astNode.getFirstDescendant(CxxGrammarImpl.declSpecifier);
if (declNode == null) {
return;
}
var declName = declNode.getTokenValue();
if (!"QLineEdit".equals(declName)) {
return;
}
astNode.getFirstDescendant(CxxGrammarImpl.initDeclaratorList).getChildren().forEach(child -> {
var fieldName = child.getFirstDescendant(CxxGrammarImpl.declaratorId).getTokenValue();
if (fieldName.toLowerCase().contains("password")) {
fieldsMap.put(fieldName, child);
// 判断声明节点的下一个节点是否为函数调用节点
var next = astNode.getNextAstNode();
do {
if (fieldName.equals(next.getTokenValue())) {
var nnext = next.getNextAstNode();
if (nnext != null && "setEchoMode".equals(nnext.getTokenValue())) {
var paramNode = nnext.getFirstDescendant(CxxGrammarImpl.parameterDeclarationList);
if (paramNode.hasDescendant(CxxGrammarImpl.qualifiedId)) {
var qualifiedNode = paramNode.getFirstDescendant(CxxGrammarImpl.qualifiedId);
if (qualifiedNode != null) {
if ("QLineEdit".equals(qualifiedNode.getFirstChild().getTokenValue())
&& "Password".equals(qualifiedNode.getLastChild().getTokenValue())) {
fieldsMap.remove(fieldName);
}
}
}
}
next = next.getNextAstNode();
} while (next != null);
}
});
}else if(astNode.is(CxxGrammarImpl.functionBody)){
List<AstNode> expressions = astNode.getDescendants(CxxGrammarImpl.expression);
boolean booPut = true;
for (AstNode ast : expressions) {
AstNode descendant = ast.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if (descendant != null) {
String methodName = descendant.getTokenValue();
if ("scanf".equals(methodName) && booPut) {
getContext().createLineViolation(this, "用户输入口令时对口令域进行掩饰,通常,用户输入的每一个字符都应该以“*”形式回显", descendant);
}else if("putchar".equals(methodName)){
List<AstNode> children = descendant.getChildren();
for(AstNode chil : children){
if("\'*\'".contains(chil.getTokenValue())){
booPut = false;
}
}
}
}
next = next.getNextAstNode();
} while (next != null);
}
}
});
}
@Override
public void leaveFile(@Nullable AstNode astNode) {
fieldsMap.values().forEach(node -> getContext().createLineViolation(this, "用户输入口令时对口令域进行掩饰,通常,用户输入的每一个字符都应该以“*”形式回显", node));
fieldsMap.clear();
}
}

@ -15,7 +15,6 @@ import org.sonar.cxx.squidbridge.annotations.ActivatedByDefault;
import org.sonar.cxx.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.cxx.squidbridge.checks.SquidCheck;
import java.util.ArrayList;
import java.util.List;
/**
@ -29,7 +28,7 @@ import java.util.List;
@SqaleConstantRemediation("5min")
public class ValidatePasswordCheck extends SquidCheck<Grammar> {
private List lists = new ArrayList();
private static final String passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@#$%^&+=!]).{10,}$";
@Override
@ -39,32 +38,13 @@ public class ValidatePasswordCheck extends SquidCheck<Grammar> {
@Override
public void visitNode(AstNode astNode) {
VerdictPassword(astNode);
checkPasswordValidationInMain(astNode);
}
AstNode functionNameNode = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId);
String functionName = functionNameNode.getTokenOriginalValue();
private void VerdictPassword(AstNode node) {
List<AstNode> nodeDescendants = node.getDescendants(CxxGrammarImpl.selectionStatement);
for (AstNode astNode : nodeDescendants) {
//判断节点是不是if节点
if ("if".equals(astNode.getToken().getValue())) {
//获取其中的参数
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList);
for (AstNode expr : astNodeList) {
lists.add(expr.getToken().getValue());
}
if (astNodeList.size() == 0) {
List<AstNode> astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression);
for (AstNode as : astNodes) {
List<AstNode> children = as.getChildren();
for (AstNode chil : children) {
lists.add(chil.getTokenValue());
}
}
}
}
//检查函数是否为main
if ("main".equals(functionName)) {
checkPasswordValidationInMain(astNode);
}
}
@ -78,10 +58,10 @@ public class ValidatePasswordCheck extends SquidCheck<Grammar> {
AstNode declaratorId = initDeclarator.getFirstDescendant(CxxGrammarImpl.declaratorId);
if (declaratorId != null) {
String variableName = declaratorId.getTokenValue();
String variableName = declaratorId.getTokenOriginalValue();
// 检查变量是否命名为password
if (variableName.toLowerCase().contains("password")) {
if ("password".equalsIgnoreCase(variableName)) {
checkPasswordInitialization(initDeclarator);
}
}
@ -99,16 +79,13 @@ public class ValidatePasswordCheck extends SquidCheck<Grammar> {
if (initializationValue != null) {
String passwordValue = initializationValue.getTokenValue();
String passwordValue = initializationValue.getTokenOriginalValue();
if (!passwordValue.matches(passwordRegex)) {
System.out.println("未通过正则校验的口令:"+passwordValue);
getContext().createLineViolation(this, "口令不匹配足够复杂度", initializationValue);
}
}
} else {
if (!lists.contains(declaration.getTokenValue())) {
getContext().createLineViolation(this, "口令不匹配足够复杂度", declaration);
}
}
}

@ -16,15 +16,10 @@ import org.sonar.cxx.squidbridge.annotations.ActivatedByDefault;
import org.sonar.cxx.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.cxx.squidbridge.checks.SquidCheck;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 在构建路径名前对输入数据进行验证确保外部输入仅包含允许的构成路径名的字符
*/
import static com.sonar.cxx.sslr.api.GenericTokenType.IDENTIFIER;
@Rule(key = "VerificationPathChecker", name = "在构建路径名前对数据进行校验", description = "对输入数据进行校验", priority = Priority.INFO, tags = {"28suo"})
@ActivatedByDefault
@ -33,122 +28,45 @@ public class VerificationPathChecker extends SquidCheck<Grammar> {
@Override
public void init() {
this.subscribeTo(CxxGrammarImpl.functionBody);
// 订阅要检查AST节点类型,用于在visitNode方法中检查该类型节点
this.subscribeTo(
CxxGrammarImpl.functionBody
);
}
public void visitNode(AstNode astNode) {
List<AstNode> descendants = astNode.getDescendants(CxxGrammarImpl.statement);
for (AstNode ast : descendants) {
if (processAst(ast)) {
break;
}
}
MethodJudge(astNode);
}
//方法拼接判断
private void MethodJudge(AstNode node){
boolean boo = true;
List<AstNode> nodeDescendants = node.getDescendants(CxxGrammarImpl.selectionStatement);
for (AstNode astNode : nodeDescendants) {
//判断节点是不是if节点
if ("if".equals(astNode.getToken().getValue())) {
//获取其中的参数
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList);
for (AstNode expr : astNodeList) {
if(expr.getTokenValue().toLowerCase().equals("filename")){
boo = false;
break;
}
}
if (astNodeList.size() == 0) {
List<AstNode> astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression);
for (AstNode as : astNodes) {
List<AstNode> children = as.getChildren();
for (AstNode chil : children) {
if(chil.getTokenValue().toLowerCase().equals("filename")){
boo = false;
break;
}
}
}
}
}
}
List<AstNode> expressions = node.getDescendants(CxxGrammarImpl.expression);
for (AstNode ast : expressions) {
AstNode descendant = ast.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if (descendant != null) {
String methodName = descendant.getTokenValue();
if ("strcat".equals(methodName) ) {
List<AstNode> astNodeList = descendant.getDescendants(CxxGrammarImpl.initializerList);
for(AstNode astNode : astNodeList){
List<AstNode> childrens = astNode.getChildren();
if (childrens != null && !childrens.isEmpty()) {
for(AstNode chil : childrens){
if(chil.getTokenValue().toLowerCase().equals("filename") ){
getContext().createLineViolation(this, "在构建路径名前对数据进行校验", chil);
break;
}
}
}
}
}
}
}
}
private boolean processAst(AstNode ast) {
List<AstNode> innerDescendants = ast.getDescendants(CxxGrammarImpl.shiftExpression);
for (AstNode desc : innerDescendants) {
if ("cin".equals(desc.getTokenValue())) {
List<AstNode> children = desc.getChildren();
for (AstNode chil : children) {
if ("IDENTIFIER".equals(chil.getName())) {
if (chil.getTokenValue().toLowerCase().contains("path")) {
boolean boo = true;
List<AstNode> exprs = ast.getDescendants(CxxGrammarImpl.postfixExpression);
for (AstNode expr : exprs) {
if (expr.getTokenValue().contains("check") || expr.getTokenValue().contains("verify") || expr.getTokenValue().contains("valid")) {
List<AstNode> astNodeList = expr.getDescendants(CxxGrammarImpl.expressionList);
for (AstNode asrList : astNodeList) {
if (chil.getTokenValue().equals(asrList.getTokenValue())) {
boo = false;
for (AstNode ast:descendants) {
List<AstNode> descendants1 = ast.getDescendants(CxxGrammarImpl.shiftExpression);
for (AstNode desc :descendants1) {
if("cin".equals(desc.getTokenValue())){
List<AstNode> children = desc.getChildren();
for (AstNode chil:children) {
if("IDENTIFIER".equals(chil.getName())){
if(chil.getTokenValue().toLowerCase().contains("path")){
boolean boo = true;
List<AstNode> exprs = astNode.getDescendants(CxxGrammarImpl.postfixExpression);
for (AstNode expr:exprs) {
if(expr.getTokenValue().contains("check") || expr.getTokenValue().contains("verify") || expr.getTokenValue().contains("valid")){
List<AstNode> astNodeList = expr.getDescendants(CxxGrammarImpl.expressionList);
for (AstNode asrList:astNodeList) {
if(chil.getTokenValue().equals(asrList.getTokenValue())){
boo = false;
}
}
}
}
}
int lineNumber = chil.getTokenLine();
if (boo && isLineInFile(lineNumber)) {
getContext().createLineViolation(this, "在构建路径名前对数据进行校验", chil);
return true;
if(boo){
getContext().createLineViolation(this, "在构建路径名前对数据进行校验", chil);
}
}
}
}
}
}
}
return false;
}
private boolean isLineInFile(int lineNumber) {
try {
int totalLines = countLines(getContext().getFile());
return lineNumber <= totalLines;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public int countLines(File file) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
int lines = 0;
while (reader.readLine() != null) lines++;
return lines;
}
}
}

@ -33,7 +33,7 @@ import java.util.Map;
@SqaleConstantRemediation("5min")
public class VirtualLockUsageChecker extends SquidCheck<Grammar> {
private List<String> keywords = Arrays.asList("add", "keyword2", "keyword3","password","name","type","token","username");
private List<String> keywords = Arrays.asList("add", "keyword2", "keyword3");
private Map<String, Map<String, AstNode>> caches = new HashMap<>();
@Override
@ -43,38 +43,31 @@ public class VirtualLockUsageChecker extends SquidCheck<Grammar> {
@Override
public void visitNode(AstNode astNode) {
AstNode descendant = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId);
if(descendant != null){
String varName = descendant.getTokenValue();
String varName = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId).getTokenOriginalValue();
for (String keyword : keywords) {
if (varName.equals(keyword) && (!caches.equals(keyword) || !caches.get(keyword).equals(varName))) {
caches.putIfAbsent(keyword, new HashMap<>());
caches.get(keyword).put(varName, astNode);
processNode(astNode, keyword);
}
for (String keyword : keywords) {
if (varName.contains(keyword) && (!caches.containsKey(keyword) || !caches.get(keyword).containsKey(varName))) {
caches.putIfAbsent(keyword, new HashMap<>());
caches.get(keyword).put(varName, astNode);
processNode(astNode, keyword);
}
}
}
private void processNode(AstNode astNode, String keyword) {
AstNode descendant = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId);
if (descendant != null){
String varName = descendant.getTokenValue();
String varName = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId).getTokenOriginalValue();
AstNode currentNode = astNode.getNextAstNode();
while (currentNode != null) {
AstNode callNode = currentNode.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if (callNode != null && callNode.getTokenValue().equalsIgnoreCase("VirtualLock")) {
List<AstNode> paramList = callNode.getDescendants(CxxGrammarImpl.expressionList);
if (paramList.stream().anyMatch(item -> item.getTokenValue().contains(keyword))) {
caches.get(keyword).remove(varName);
break;
}
AstNode currentNode = astNode.getNextAstNode();
while (currentNode != null) {
AstNode callNode = currentNode.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if (callNode != null && callNode.getTokenOriginalValue().equalsIgnoreCase("VirtualLock")) {
List<AstNode> paramList = callNode.getDescendants(CxxGrammarImpl.expressionList);
if (paramList.stream().anyMatch(item -> item.getTokenOriginalValue().contains(keyword))) {
caches.get(keyword).remove(varName);
break;
}
currentNode = currentNode.getNextSibling();
}
currentNode = currentNode.getNextSibling();
}
}
@ -86,6 +79,7 @@ public class VirtualLockUsageChecker extends SquidCheck<Grammar> {
private void reportViolations() {
caches.values().forEach(cache ->
cache.values().forEach(item -> {
System.out.println("特定字段"+item.getFirstDescendant(CxxGrammarImpl.declaratorId).getTokenOriginalValue()+"未使用VirtualLock()函数锁定存放敏感信息的内存");
getContext().createLineViolation(this, "特定字段未使用VirtualLock()函数锁定存放敏感信息的内存", item);
})
);

@ -1,259 +0,0 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package org.sonar.cxx.squidbridge; // cxx: in use
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.sonar.cxx.sslr.api.AstNode;
import com.sonar.cxx.sslr.api.Grammar;
import com.sonar.cxx.sslr.api.RecognitionException;
import com.sonar.cxx.sslr.impl.Parser;
import com.sonar.cxx.sslr.impl.ast.AstWalker;
import java.io.File;
import java.io.InterruptedIOException;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.cxx.squidbridge.api.AnalysisException;
import org.sonar.cxx.squidbridge.api.SourceCodeSearchEngine;
import org.sonar.cxx.squidbridge.api.SourceCodeTreeDecorator;
import org.sonar.cxx.squidbridge.api.SourceProject;
import org.sonar.cxx.squidbridge.indexer.SquidIndex;
import org.sonar.cxx.squidbridge.measures.MetricDef;
public class AstScanner<G extends Grammar> {
private static final Logger LOG = Loggers.get(AstScanner.class);
private final List<SquidAstVisitor<G>> visitors;
private final Parser<G> parser;
private final SquidAstVisitorContextImpl<G> context;
private final SquidIndex indexer = new SquidIndex();
private final MetricDef[] metrics;
private final MetricDef filesMetric;
protected AstScanner(Builder<G> builder) {
this.visitors = Lists.newArrayList(builder.visitors);
this.parser = builder.baseParser;
this.context = builder.context;
this.context.setGrammar(parser.getGrammar());
this.context.getProject().setSourceCodeIndexer(indexer);
this.context.setCommentAnalyser(builder.commentAnalyser);
this.metrics = builder.metrics;
this.filesMetric = builder.filesMetric;
indexer.index(context.getProject());
}
public SourceCodeSearchEngine getIndex() {
return indexer;
}
public void scanFile(File file) {
scanFiles(java.util.List.of(file));
}
public void scanInputFile(InputFile inputFile) {
scanInputFiles(java.util.List.of(inputFile));
}
public void scanFiles(Collection<File> files) {
initVisitors();
var astWalker = new AstWalker(visitors);
for (var file : files) {
checkCancel();
context.setFile(file, filesMetric);
Exception parseException = null;
AstNode ast = null;
try {
try {
ast = parser.parse(file);
} catch (Exception e) {
parseException = handleParseException(file, e);
}
walkAndVisit(astWalker, ast, parseException);
} catch (Throwable e) {
throw new AnalysisException("Unable to parse file: " + file.getAbsolutePath(), e);
}
}
destroyVisitors();
decorateSquidTree();
}
public void scanInputFiles(Iterable<InputFile> inputFiles) {
initVisitors();
var astWalker = new AstWalker(visitors);
for (var inputFile : inputFiles) {
var file = new File(inputFile.uri().getPath());
checkCancel();
context.setInputFile(inputFile, filesMetric);
Exception parseException = null;
AstNode ast = null;
try {
try {
ast = parser.parse(inputFile.contents());
} catch (Exception e) {
parseException = handleParseException(file, e);
}
walkAndVisit(astWalker, ast, parseException);
} catch (Throwable e) {
LOG.error("Unable to parse file: " + file.getAbsolutePath(), e);
}
}
destroyVisitors();
decorateSquidTree();
}
private static Exception handleParseException(File file, Exception e) {
checkInterrupted(e);
if (e instanceof RecognitionException) {
LOG.error("Unable to parse file: " + file.getAbsolutePath());
LOG.error(e.getMessage());
} else {
LOG.error("Unable to parse file: " + file.getAbsolutePath(), e);
}
return e;
}
private void walkAndVisit(AstWalker astWalker, AstNode ast, @Nullable Exception parseException) throws Throwable {
if (parseException == null) {
astWalker.walkAndVisit(ast);
} else {
// process parse error
for (var visitor : visitors) {
visitor.visitFile(ast);
}
for (var visitor : visitors) {
if (visitor instanceof AstScannerExceptionHandler) {
if (parseException instanceof RecognitionException) {
((AstScannerExceptionHandler) visitor)
.processRecognitionException((RecognitionException) parseException);
} else {
((AstScannerExceptionHandler) visitor).processException(parseException);
}
}
}
for (var visitor : visitors) {
visitor.leaveFile(ast);
}
}
context.popTillSourceProject();
}
private void initVisitors() {
for (var visitor : visitors) {
visitor.init();
}
}
private void destroyVisitors() {
for (var visitor : visitors) {
visitor.destroy();
}
}
/**
* Checks if the root cause of the thread is related to an interrupt.
* Note that when such an exception is thrown, the interrupt flag is reset.
*/
private static void checkInterrupted(Exception e) {
Throwable cause = Throwables.getRootCause(e);
if (cause instanceof InterruptedException || cause instanceof InterruptedIOException) {
throw new AnalysisException("Analysis cancelled", e);
}
}
private static void checkCancel() {
if (Thread.interrupted()) {
throw new AnalysisException("Analysis cancelled");
}
}
protected void decorateSquidTree() {
if (metrics != null && metrics.length > 0) {
SourceProject project = context.getProject();
var decorator = new SourceCodeTreeDecorator(project);
decorator.decorateWith(metrics);
}
}
public static <G extends Grammar> Builder<G> builder(SquidAstVisitorContextImpl<G> context) {
return new Builder<>(context);
}
public static class Builder<G extends Grammar> {
private Parser<G> baseParser;
private final List<SquidAstVisitor<G>> visitors = Lists.newArrayList();
private final SquidAstVisitorContextImpl<G> context;
private CommentAnalyser commentAnalyser;
private MetricDef[] metrics;
private MetricDef filesMetric;
public Builder(SquidAstVisitorContextImpl<G> context) {
checkNotNull(context, "context cannot be null");
this.context = context;
}
public Builder<G> setBaseParser(Parser<G> baseParser) {
checkNotNull(baseParser, "baseParser cannot be null");
this.baseParser = baseParser;
return this;
}
public Builder<G> setCommentAnalyser(CommentAnalyser commentAnalyser) {
checkNotNull(commentAnalyser, "commentAnalyser cannot be null");
this.commentAnalyser = commentAnalyser;
return this;
}
public Builder<G> withSquidAstVisitor(SquidAstVisitor<G> visitor) {
checkNotNull(visitor, "visitor cannot be null");
if(visitor.getContext() == null){
visitor.setContext(context);
visitors.add(visitor);
}
return this;
}
public Builder<G> withMetrics(MetricDef... metrics) {
for (var metric : metrics) {
checkNotNull(metric, "metrics cannot be null");
}
this.metrics = metrics.clone();
return this;
}
public Builder<G> setFilesMetric(MetricDef filesMetric) {
checkNotNull(filesMetric, "filesMetric cannot be null");
this.filesMetric = filesMetric;
return this;
}
public AstScanner<G> build() {
checkState(baseParser != null, "baseParser must be set");
checkState(commentAnalyser != null, "commentAnalyser must be set");
checkState(filesMetric != null, "filesMetric must be set");
return new AstScanner<>(this);
}
}
}

@ -30,8 +30,6 @@ public class BufferDataCheckerTest {
.next().atLine(17).withMessage("应对读写缓冲区的数据长度进行检查")
.next().atLine(30).withMessage("应对读写缓冲区的数据长度进行检查")
.next().atLine(43).withMessage("应对读写缓冲区的数据长度进行检查")
.next().atLine(67).withMessage("应对读写缓冲区的数据长度进行检查")
.next().atLine(73).withMessage("应对读写缓冲区的数据长度进行检查")
.noMore();
}
}

@ -29,7 +29,6 @@ public class DLLVerifyCheckerTest {
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(17).withMessage("在动态加载库前对输入数据进行验证")
.next().atLine(43).withMessage("在动态加载库前对输入数据进行验证")
.next().atLine(83).withMessage("在动态加载库前对输入数据进行验证")
.noMore();
}
}

@ -30,7 +30,6 @@ public class EncryptionAlgorithmCheckerTest {
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(9).withMessage("特定字段未使用单向加密算法对口令进行加密并存储")
.next().atLine(10).withMessage("特定字段未使用单向加密算法对口令进行加密并存储")
.noMore();
}

@ -27,8 +27,7 @@ public class FileAccessCheckerTest {
var tester = CxxFileTesterHelper.create("FileAccessChecker.cc");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(14).withMessage("在访问文件或目录前需要对路径名进行验证")
.next().atLine(17).withMessage("在访问文件或目录前需要对路径名进行验证")
.next().atLine(13).withMessage("在访问文件或目录前需要对路径名进行验证")
.noMore();
}
}

@ -30,7 +30,6 @@ public class IntegerCountVerifyCheckerTest {
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(10).withMessage("來自用戶的整型数据进行算术运算应进行验证")
.next().atLine(10).withMessage("來自用戶的整型数据进行算术运算应进行验证")
.next().atLine(18).withMessage("來自用戶的整型数据进行算术运算应进行验证")
.noMore();
}
}

@ -23,7 +23,7 @@ public class NumericalCopyTest {
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(15).withMessage("应返回该私有数值的副本")
// .next().atLine(20).withMessage("应返回该私有数值的副本")
.next().atLine(25).withMessage("应返回该私有数值的副本")
.noMore();
}

@ -31,7 +31,6 @@ public class PRNGVerifyCheckerTest {
.next().atLine(8).withMessage("应使用目前被业界专家认为较强的经过良好审核的加密PRNG算法")
.next().atLine(11).withMessage("应使用目前被业界专家认为较强的经过良好审核的加密PRNG算法")
.next().atLine(14).withMessage("应使用目前被业界专家认为较强的经过良好审核的加密PRNG算法")
.next().atLine(18).withMessage("应使用目前被业界专家认为较强的经过良好审核的加密PRNG算法")
.noMore();
}
}

@ -29,8 +29,6 @@ public class PassWordCountCheckerTest {
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(10).withMessage("使用盐值计算散列值")
.next().atLine(31).withMessage("使用盐值计算散列值")
.next().atLine(43).withMessage("使用盐值计算散列值")
.noMore();
}
}

@ -29,8 +29,6 @@ public class PathVerifyCheckerTest {
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(4).withMessage("使用关键资源时指定资源所在的路径")
.next().atLine(5).withMessage("使用关键资源时指定资源所在的路径")
.next().atLine(18).withMessage("使用关键资源时指定资源所在的路径")
.next().atLine(31).withMessage("使用关键资源时指定资源所在的路径")
.noMore();
}
}

@ -27,7 +27,7 @@ public class ReallocMainCheckerTest {
var tester = CxxFileTesterHelper.create("ReallocMainChecker.cc");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(27).withMessage("使用realloc函数前应先清敏感信息")
.next().atLine(27).withMessage("使用realloc函数前应先清敏感信息")
.noMore();
}

@ -28,8 +28,7 @@ public class SQLVerifyCheckerTest {
var tester = CxxFileTesterHelper.create("SQLVerifyChecker.cc");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
// .next().atLine(26).withMessage("在使用SQL语句前对输入数据进行验证")
.next().atLine(5).withMessage("在使用SQL语句前对输入数据进行验证")
.next().atLine(26).withMessage("在使用SQL语句前对输入数据进行验证")
.noMore();
}
}

@ -28,7 +28,6 @@ public class SendMessageCheckerTest {
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(13).withMessage("发送敏感信息前应对敏感信息进行加密")
.next().atLine(14).withMessage("发送敏感信息前应对敏感信息进行加密")
.noMore();
}
}

@ -29,7 +29,6 @@ public class UserInputPasswordCheckerTest {
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(18).withMessage("用户输入口令时对口令域进行掩饰,通常,用户输入的每一个字符都应该以“*”形式回显")
.next().atLine(22).withMessage("用户输入口令时对口令域进行掩饰,通常,用户输入的每一个字符都应该以“*”形式回显")
.next().atLine(59).withMessage("用户输入口令时对口令域进行掩饰,通常,用户输入的每一个字符都应该以“*”形式回显")
.noMore();
}
}

@ -21,7 +21,6 @@ public class VerificationPathCheckerTest {
var tester = CxxFileTesterHelper.create("VerificationPathChecker.cc");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(11).withMessage("在构建路径名前对数据进行校验")
.next().atLine(12).withMessage("在构建路径名前对数据进行校验")
.noMore();
}

@ -30,9 +30,6 @@ public class VirtualLockUsageCheckerTest {
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(8).withMessage("特定字段未使用VirtualLock()函数锁定存放敏感信息的内存")
.next().atLine(10).withMessage("特定字段未使用VirtualLock()函数锁定存放敏感信息的内存")
.next().atLine(12).withMessage("特定字段未使用VirtualLock()函数锁定存放敏感信息的内存")
.next().atLine(14).withMessage("特定字段未使用VirtualLock()函数锁定存放敏感信息的内存")
.noMore();
}
}

@ -60,16 +60,4 @@ int main() {
std::cout << std::endl;
return 0;
}
void vulnerable_function(char *input) {
char buffer[10];
strcpy(buffer, input); // 没有检查输入长度,可能导致缓冲区溢出
}
void example(){
char value[11];
printf("Enter The Value");
scanf("%s",values);// 没有检查输入长度,可能导致缓冲区溢出
}
}

@ -75,10 +75,4 @@ int main()
#endif
return 0;
}
void load(char * libaryName){
char path[32] = "C:\\";
strcat(path,libaryName);
HANDLE hlib = LoadLibrary(path);
}

@ -7,7 +7,7 @@ using namespace bcrypt;
int main() {
// 用户输入的原始密码
string password = "userPassword123";
AESEncryption aesEncryptor;
// 使用cpp-bcrypt生成盐和哈希
// bcrypt::generate_salt(); // 生成一个随机盐
// string salt = bcrypt::get_salt();

@ -1,6 +1,5 @@
#include <openssl/aes.h>// error
#include <openssl/des.h>// error
#include "aes.h"// error
#include <string.h>
void encryptWithAES(const unsigned char* plaintext, size_t plaintext_len,
@ -32,10 +31,4 @@ int main() {
// ... 然后可以进一步处理密文 ...
return 0;
}
int encryptor(char* input,char* output)//加密函数,输出参数返回加密后的字符串
{
AESEncryption aesEncryptor;
int r= aesEncryptor.enc(input,output);//使用双向可逆的 AES加密算法
}

@ -10,12 +10,9 @@ int main() {
int a = 5;
if (a<4) {
if (a<5) {
ifstream file(filePath);
File * file;
file = fopen(filePath,"r");
cout << "File opened successfully." << endl;
file.close();

@ -11,13 +11,4 @@ int main() {
// std::cout << "两数之差:" << num1 - num2 << std::endl;
// std::cout << "两数之积:" << num1 * num2 << std::endl;
return 0;
}
unsigned int num;
void exfun(){
unsigned int mrsp = pacjget_get_int();
char * response = malloc((mrsp + num) * sizeof(char *));
unsigned int i;
for(i =0;i<mrsp;i++){
response[i] = packet_get_string();
}
}

@ -13,7 +13,7 @@
2024.01.14 16:05:34 INFO web[][o.s.s.u.SystemPasscodeImpl] System authentication by passcode is disabled
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy C# Code Quality and Security / 9.8.0.76515 / c1515bad8ebe3e38e102b68fdec8c429669ec560
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy C++ 信息安全性设计准则 / 1.0 / 1390585ba547ab6e3fe269c9d341cef06e44f08e
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Chinese Pack / 10.2 / null
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Clean as You Code / 2.1.0.500 / 4a2d47cf125d03ebacf43536a3897c168deb1b0a
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Configuration detection for Code Quality and Security / 1.3.0.654 / 63073f0270b2c4754afa58eb8b5ea04e2eebf1a4
@ -24,7 +24,7 @@
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Flex Code Quality and Security / 2.10.0.3458 / 3ef14c50cfd03e5b40a2270fc6e8edc5c49dedcd
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Go Code Quality and Security / 1.14.0.4481 / dcfff811316898a16bf1c6ff191dd3a5d84d3307
2024.01.14 16:05:36 INFO web[][o.s.s.p.ServerPluginManager] Deploy Groovy / 1.8 / 6f5ddad1c7cf86e39cd9a8fc0be896660b4d4b61
@ -475,7 +475,7 @@
2024.01.14 16:51:09 INFO web[][o.s.s.u.SystemPasscodeImpl] System authentication by passcode is disabled
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy C# Code Quality and Security / 9.8.0.76515 / c1515bad8ebe3e38e102b68fdec8c429669ec560
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy C++ 信息安全性设计准则 / 1.0 / 1390585ba547ab6e3fe269c9d341cef06e44f08e
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Chinese Pack / 10.2 / null
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Clean as You Code / 2.1.0.500 / 4a2d47cf125d03ebacf43536a3897c168deb1b0a
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Configuration detection for Code Quality and Security / 1.3.0.654 / 63073f0270b2c4754afa58eb8b5ea04e2eebf1a4
@ -486,7 +486,7 @@
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Flex Code Quality and Security / 2.10.0.3458 / 3ef14c50cfd03e5b40a2270fc6e8edc5c49dedcd
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Go Code Quality and Security / 1.14.0.4481 / dcfff811316898a16bf1c6ff191dd3a5d84d3307
2024.01.14 16:51:10 INFO web[][o.s.s.p.ServerPluginManager] Deploy Groovy / 1.8 / 6f5ddad1c7cf86e39cd9a8fc0be896660b4d4b61
@ -850,7 +850,7 @@
2024.01.14 17:22:18 INFO web[][o.s.s.u.SystemPasscodeImpl] System authentication by passcode is disabled
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy C# Code Quality and Security / 9.8.0.76515 / c1515bad8ebe3e38e102b68fdec8c429669ec560
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy C++ 信息安全性设计准则 / 1.0 / 1390585ba547ab6e3fe269c9d341cef06e44f08e
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Chinese Pack / 10.2 / null
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Clean as You Code / 2.1.0.500 / 4a2d47cf125d03ebacf43536a3897c168deb1b0a
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Configuration detection for Code Quality and Security / 1.3.0.654 / 63073f0270b2c4754afa58eb8b5ea04e2eebf1a4
@ -861,7 +861,7 @@
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Flex Code Quality and Security / 2.10.0.3458 / 3ef14c50cfd03e5b40a2270fc6e8edc5c49dedcd
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Go Code Quality and Security / 1.14.0.4481 / dcfff811316898a16bf1c6ff191dd3a5d84d3307
2024.01.14 17:22:19 INFO web[][o.s.s.p.ServerPluginManager] Deploy Groovy / 1.8 / 6f5ddad1c7cf86e39cd9a8fc0be896660b4d4b61
@ -1254,7 +1254,7 @@
2024.01.14 17:49:17 INFO web[][o.s.s.u.SystemPasscodeImpl] System authentication by passcode is disabled
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy C# Code Quality and Security / 9.8.0.76515 / c1515bad8ebe3e38e102b68fdec8c429669ec560
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy C++ 信息安全性设计准则 / 1.0 / 1390585ba547ab6e3fe269c9d341cef06e44f08e
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Chinese Pack / 10.2 / null
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Clean as You Code / 2.1.0.500 / 4a2d47cf125d03ebacf43536a3897c168deb1b0a
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Configuration detection for Code Quality and Security / 1.3.0.654 / 63073f0270b2c4754afa58eb8b5ea04e2eebf1a4
@ -1265,7 +1265,7 @@
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Flex Code Quality and Security / 2.10.0.3458 / 3ef14c50cfd03e5b40a2270fc6e8edc5c49dedcd
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Go Code Quality and Security / 1.14.0.4481 / dcfff811316898a16bf1c6ff191dd3a5d84d3307
2024.01.14 17:49:18 INFO web[][o.s.s.p.ServerPluginManager] Deploy Groovy / 1.8 / 6f5ddad1c7cf86e39cd9a8fc0be896660b4d4b61
@ -1658,7 +1658,7 @@
2024.01.14 18:19:14 INFO web[][o.s.s.u.SystemPasscodeImpl] System authentication by passcode is disabled
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy C# Code Quality and Security / 9.8.0.76515 / c1515bad8ebe3e38e102b68fdec8c429669ec560
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy C++ 信息安全性设计准则 / 1.0 / 1390585ba547ab6e3fe269c9d341cef06e44f08e
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Chinese Pack / 10.2 / null
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Clean as You Code / 2.1.0.500 / 4a2d47cf125d03ebacf43536a3897c168deb1b0a
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Configuration detection for Code Quality and Security / 1.3.0.654 / 63073f0270b2c4754afa58eb8b5ea04e2eebf1a4
@ -1669,7 +1669,7 @@
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Flex Code Quality and Security / 2.10.0.3458 / 3ef14c50cfd03e5b40a2270fc6e8edc5c49dedcd
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Go Code Quality and Security / 1.14.0.4481 / dcfff811316898a16bf1c6ff191dd3a5d84d3307
2024.01.14 18:19:15 INFO web[][o.s.s.p.ServerPluginManager] Deploy Groovy / 1.8 / 6f5ddad1c7cf86e39cd9a8fc0be896660b4d4b61
@ -2062,7 +2062,7 @@
2024.01.14 18:48:41 INFO web[][o.s.s.u.SystemPasscodeImpl] System authentication by passcode is disabled
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy C# Code Quality and Security / 9.8.0.76515 / c1515bad8ebe3e38e102b68fdec8c429669ec560
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy C++ 信息安全性设计准则 / 1.0 / 1390585ba547ab6e3fe269c9d341cef06e44f08e
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Checkstyle / 10.12.3 /
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Chinese Pack / 10.2 / null
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Clean as You Code / 2.1.0.500 / 4a2d47cf125d03ebacf43536a3897c168deb1b0a
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Configuration detection for Code Quality and Security / 1.3.0.654 / 63073f0270b2c4754afa58eb8b5ea04e2eebf1a4
@ -2073,7 +2073,7 @@
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Example Plugin for SonarQube 10.x / 10.0.0 / null
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Findbugs / 4.2.5 /
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Flex Code Quality and Security / 2.10.0.3458 / 3ef14c50cfd03e5b40a2270fc6e8edc5c49dedcd
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Go Code Quality and Security / 1.14.0.4481 / dcfff811316898a16bf1c6ff191dd3a5d84d3307
2024.01.14 18:48:42 INFO web[][o.s.s.p.ServerPluginManager] Deploy Groovy / 1.8 / 6f5ddad1c7cf86e39cd9a8fc0be896660b4d4b61

@ -4,8 +4,8 @@ class MyClass {
private:
std::array<int, 10> privateArray;
public:
// 假设初始化已经在构造函数或其他地方完成
// 返回的是私有数组的副本
// 假设初始化已经在构造函数或其他地方完成
// 返回的是私有数组的副本
// const std::array<int, 10> getPrivateArrayRef() const {
// return privateArray;
// }
@ -15,8 +15,14 @@ public:
return privateArray; // error
}
// 返回的是私有数组的指针
// int* getPrivateArrayPtr() {
// return privateArray.data(); // error
// 返回的是私有数组的副本
// int getPrivateArrayPtr() {
// return privateArray.data();
// }
}
// 返回的是私有数组的指针
int* getPrivateArrayPtr() {
return privateArray.data(); // error
}
};

@ -14,9 +14,5 @@ int main(){
std::knuth_b knuthGenerator(rd()); // 使用更好的随机种子初始化knuth_b
std::cout << knuthGenerator() << std::endl;
for(i=0;i<8;i++){
num = 10*rand()/(RAND_MAX+1);
iv[i] = num + '0';
}
return 0;
}

@ -17,28 +17,4 @@ int main() {
std::string input;
test(input);
return 0;
}
void calculate_hash(const char *password, unsigned char *hash) {
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, password, strlen(password));
SHA256_Final(hash, &ctx);
}
int main() {
const char *password = "mysecretpassword";
unsigned char hash[SHA256_DIGEST_LENGTH];
calculate_hash(password, hash);
printf("Password: %s\n", password);
printf("SHA256 Hash: ");
for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
printf("%02x", hash[i]);
}
printf("\n");
return 0;
}
void ef(cahr* password){
char psw[1024] = {0};
inr r= encryptor(password,psw);
}
}

@ -5,28 +5,4 @@ int main() {
std::string testString1 = "User\\Documents";
//std::String testString1 = "C:\\Users\\User\\Documents";
return 0;
}
void load_resource(const char *filename) {
char buffer[100];
FILE *fp;
// 假设程序加载资源的路径是固定的 "/path/to/resources/"
const char *resource_path = "/path/to/resources/";
// 构建资源文件的完整路径
snprintf(buffer, sizeof(buffer), "%s%s", resource_path, filename);
// 打开资源文件
fp = fopen(buffer, "r");
if (fp == NULL) {
printf("无法打开文件 %s\n", buffer);
return;
}
// 读取文件内容并处理
// 假设这里是处理文件内容的代码...
// 关闭文件
fclose(fp);
}
void example_fun(void){
//攻击者可在搜索优先级更高的文件夹中放入和dir同名的恶意程序导致 command的内容无法正确执行
system(command);//本例中 command=“dir.exe E:\\data”
}

@ -1,7 +1,53 @@
#include<stdio.h>
#include<string.h>
void sqlQuery(char * name){
char sqlQuery[64] = "select * from cus where userid=";
strcat(sqlQuery,name);
strcat(sqlQuery,"'");
#include <iostream>
#include <mysql_driver.h> // MySQL Connector/C++库头文件
#include <mysql_connection.h>
// 假设你已经有了一个sanitizeString函数,用于清理SQL注入风险
std::string sanitizeString(const std::string& input) {
// 在这里实现SQL字符串清理逻辑
return cleanedInput;
}
int main() {
try {
sql::mysql::MySQL_Driver *driver;
sql::Connection *con;
// 初始化数据库连接
driver = sql::mysql::get_mysql_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "username", "password");
con->setSchema("your_database");
std::string inputQuery = "";
std::cout << "请输入SQL查询语句: ";
std::getline(std::cin, inputQuery);
// 对输入的SQL语句进行验证和处理
std::string sqlQuery = sanitizeString(inputQuery);
// 创建并执行SQL语句
sql::Statement *stmt = con->createStatement();
sql::ResultSet *res = stmt->executeQuery(sqlQuery);
// 处理查询结果
while (res->next()) {
// 从结果集中获取数据并进行处理
// 这里假设你知道第一列的名字,如果不是,请替换为实际列名
std::string resultData = res->getString("your_column_name");
std::cout << "查询结果: " << resultData << std::endl;
}
delete stmt;
delete res;
delete con;
}
catch (sql::SQLException &e) {
std::cerr << "# ERR: SQLException in " << __FILE__;
std::cerr << "(" << __FUNCTION__ << ") on line " << __LINE__ << std::endl;
std::cerr << "# ERR: " << e.what();
std::cerr << " (MySQL error code: " << e.getErrorCode();
std::cerr << ", SQLState: " << e.getSQLState() << " )" << std::endl;
}
return 0;
}

@ -11,7 +11,7 @@ int main() {
std::string param = "Hello, Server!";
send(socket_fd,param.c_str(), param.size()); // 发送信息
send_message(address);
// ...其他处理,如关闭连接等
close(socket_fd);

@ -46,18 +46,4 @@ int main(int argc, char *argv[])
LoginDialog dialog;
dialog.show();
return app.exec();
}
void exaa(){
char password[MAX_STR_LEN];
int i =0;
char c ='0';
printf("Please password:");
while(i<MAX_STR_LEN && c != '\n')
{
// putchar('*');
scanf("%c",&c);
password[i] =c;
i++;
}
}

@ -3,13 +3,14 @@
using namespace std;
// 假设以下两个函数用于检查和验证路径
void checkPath(const string& path);
void verifyPath(const string& path);
void checkPath(const std::string& path);
void verifyPath(const std::string& path);
int main(){
string userPath;
cout << "Enter a path: ";
cin >> userPath;
strcat(path,filename);
// 在获取用户输入之后立即对其进行验证
// checkPath(userPath);
// verifyPath(userPath);

@ -7,11 +7,10 @@ int main() {
string add = "北京市"; //error
string keyword2 = "北京市"; //error
string keyword3 = "北京市"; //error
// string keyword2 = "北京市"; //error
//
// string keyword3 = "北京市"; //error
char * password = "";
// 利用vector<char>管理内存
// vector<char> addressBuffer(add.begin(), add.end());
//

@ -110,13 +110,6 @@
<version>1.28</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
@ -148,61 +141,6 @@
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/LICENSE*</exclude>
<exclude>META-INF/NOTICE*</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.SF</exclude>
<exclude>LICENSE*</exclude>
<exclude>NOTICE*</exclude>
</excludes>
</filter>
<filter>
<artifact>cglib:cglib-nodep</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>org.sonarsource.java:java-frontend</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>xerces:xercesImpl</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>xml-apis:xml-apis</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>org.apache.tomcat.embed:tomcat-embed-jasper</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<!-- this is needed because org.apache.el.ExpressionFactoryImpl is instantiated with reflection -->
<filter>
<artifact>org.apache.tomcat.embed:tomcat-embed-el</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>

@ -1,66 +0,0 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java;
import java.util.Arrays;
import org.sonar.api.config.Configuration;
import org.sonar.api.resources.AbstractLanguage;
/**
* Java language implementation
*
* @since 1.3
*/
public class Java extends AbstractLanguage {
/**
* Java key
*/
public static final String KEY = "java";
/**
* Java name
*/
public static final String NAME = "Java";
/**
* Key of the file suffix parameter
*/
public static final String FILE_SUFFIXES_KEY = "sonar.java.file.suffixes";
/**
* Default Java fil
* es knows suffixes
*/
public static final String DEFAULT_FILE_SUFFIXES = ".java,.jav";
/**
* Settings of the plugin.
*/
private final Configuration settings;
/**
* Default constructor
*/
public Java(Configuration settings) {
super(KEY, NAME);
this.settings = settings;
}
/**
* {@inheritDoc}
*
* @see org.sonar.api.resources.AbstractLanguage#getFileSuffixes()
*/
@Override
public String[] getFileSuffixes() {
String[] suffixes = Arrays.stream(settings.getStringArray(Java.FILE_SUFFIXES_KEY)).filter(s -> s != null && !s.trim().isEmpty()).toArray(String[]::new);
return suffixes.length > 0 ? suffixes : DEFAULT_FILE_SUFFIXES.split(",");
}
}

@ -1,200 +0,0 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package com.keyware.sonar.java;
import java.io.File;
import java.util.*;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.Phase;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
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.config.Configuration;
import org.sonar.api.issue.NoSonarFilter;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.scan.issue.filter.FilterableIssue;
import org.sonar.api.scan.issue.filter.IssueFilterChain;
import org.sonar.java.JavaFrontend;
import org.sonar.java.Measurer;
import org.sonar.java.SonarComponents;
import org.sonar.java.annotations.VisibleForTesting;
import org.sonar.java.checks.CheckList;
import org.sonar.java.filters.PostAnalysisIssueFilter;
import org.sonar.java.jsp.Jasper;
import org.sonar.java.model.GeneratedFile;
import org.sonar.java.model.JavaVersionImpl;
import org.sonar.java.se.SymbolicExecutionVisitor;
import org.sonar.java.se.checks.SECheck;
import org.sonar.plugins.java.api.JavaCheck;
import org.sonar.plugins.java.api.JavaResourceLocator;
import org.sonar.plugins.java.api.JavaVersion;
import org.sonarsource.analyzer.commons.BuiltInQualityProfileJsonLoader;
import org.sonarsource.performance.measure.PerformanceMeasure;
import static org.sonar.api.rules.RuleAnnotationUtils.getRuleKey;
@Phase(name = Phase.Name.PRE)
public class KeyJavaSensor implements Sensor{
private static final Logger LOG = LoggerFactory.getLogger(KeyJavaSensor.class);
private static final String PERFORMANCE_MEASURE_ACTIVATION_PROPERTY = "sonar.java.performance.measure";
private static final String PERFORMANCE_MEASURE_FILE_PATH_PROPERTY = "sonar.java.performance.measure.path";
private static final String PERFORMANCE_MEASURE_DESTINATION_FILE = "sonar.java.performance.measure.json";
static final String SONAR_WAY_PATH = "/org/sonar/l10n/java/rules/java/Sonar_way_profile.json";
private final SonarComponents sonarComponents;
private final FileSystem fs;
private final JavaResourceLocator javaResourceLocator;
private final Configuration settings;
private final NoSonarFilter noSonarFilter;
@Nullable
private final Jasper jasper;
private final PostAnalysisIssueFilter postAnalysisIssueFilter;
public KeyJavaSensor(SonarComponents sonarComponents, FileSystem fs,
JavaResourceLocator javaResourceLocator, Configuration settings,
NoSonarFilter noSonarFilter,
PostAnalysisIssueFilter postAnalysisIssueFilter, @Nullable Jasper jasper) {
this.noSonarFilter = noSonarFilter;
this.sonarComponents = sonarComponents;
this.fs = fs;
this.javaResourceLocator = javaResourceLocator;
this.settings = settings;
this.postAnalysisIssueFilter = postAnalysisIssueFilter;
this.jasper = jasper;
this.sonarComponents.registerMainCheckClasses(CheckList.REPOSITORY_KEY, CheckList.getJavaChecks());
}
@Override
public void describe(SensorDescriptor descriptor) {
descriptor.onlyOnLanguage(Java.KEY).name("KeyJavaSensor");
}
@Override
public void execute(SensorContext context) {
PerformanceMeasure.Duration sensorDuration = createPerformanceMeasureReport(context);
sonarComponents.setSensorContext(context);
sonarComponents.setCheckFilter(createCheckFilter(sonarComponents.isAutoScanCheckFiltering()));
Measurer measurer = new Measurer(context, noSonarFilter);
JavaFrontend frontend = new JavaFrontend(getJavaVersion(), sonarComponents, measurer, javaResourceLocator, postAnalysisIssueFilter,
insertSymbolicExecutionVisitor(sonarComponents.mainChecks()));
frontend.scan(getSourceFiles(), getTestFiles(), runJasper(context));
sensorDuration.stop();
}
private UnaryOperator<List<JavaCheck>> createCheckFilter(boolean isAutoScanCheckFiltering) {
if (isAutoScanCheckFiltering) {
Set<RuleKey> autoScanCompatibleRules = new HashSet<>(KeyJavaSensor.sonarJavaSonarWayRuleKeys());
CheckList.getJavaChecksNotWorkingForAutoScan().stream()
.map(checkClass -> RuleKey.of(CheckList.REPOSITORY_KEY, getRuleKey(checkClass)))
.forEach(autoScanCompatibleRules::remove);
return checks -> checks.stream()
.filter(check -> sonarComponents.getRuleKey(check).map(autoScanCompatibleRules::contains).orElse(false))
.collect(Collectors.toList());
} else {
return UnaryOperator.identity();
}
}
static Set<RuleKey> sonarJavaSonarWayRuleKeys() {
return BuiltInQualityProfileJsonLoader.loadActiveKeysFromJsonProfile(SONAR_WAY_PATH).stream()
.map(rule -> RuleKey.of(CheckList.REPOSITORY_KEY, rule))
.collect(Collectors.toSet());
}
private static PerformanceMeasure.Duration createPerformanceMeasureReport(SensorContext context) {
return PerformanceMeasure.reportBuilder()
.activate(context.config().get(PERFORMANCE_MEASURE_ACTIVATION_PROPERTY).filter("true"::equals).isPresent())
.toFile(context.config().get(PERFORMANCE_MEASURE_FILE_PATH_PROPERTY)
.filter(path -> !path.isEmpty())
.orElseGet(() -> Optional.ofNullable(context.fileSystem().workDir())
.filter(File::exists)
.map(file -> file.toPath().resolve(PERFORMANCE_MEASURE_DESTINATION_FILE).toString())
.orElse(null)))
.appendMeasurementCost()
.start("KeyJavaSensor");
}
@VisibleForTesting
static JavaCheck[] insertSymbolicExecutionVisitor(List<JavaCheck> checks) {
List<SECheck> seChecks = checks.stream()
.filter(SECheck.class::isInstance)
.map(SECheck.class::cast)
.collect(Collectors.toList());
if (seChecks.isEmpty()) {
LOG.info("No rules with 'symbolic-execution' tag were enabled,"
+ " the Symbolic Execution Engine will not run during the analysis.");
return checks.toArray(new JavaCheck[0]);
}
List<JavaCheck> newList = new ArrayList<>(checks);
// insert an instance of SymbolicExecutionVisitor before the first SECheck
newList.add(newList.indexOf(seChecks.get(0)), new SymbolicExecutionVisitor(seChecks));
return newList.toArray(new JavaCheck[0]);
}
private Collection<GeneratedFile> runJasper(SensorContext context) {
if (sonarComponents.isAutoScan()) {
// for security reasons, do not run jasper to generate code in autoscan mode
return Collections.emptyList();
}
return jasper != null ? jasper.generateFiles(context, sonarComponents.getJavaClasspath()) : Collections.emptyList();
}
private Iterable<InputFile> getSourceFiles() {
return javaFiles(InputFile.Type.MAIN);
}
private Iterable<InputFile> getTestFiles() {
return javaFiles(InputFile.Type.TEST);
}
private Iterable<InputFile> javaFiles(InputFile.Type type) {
return fs.inputFiles(fs.predicates().and(fs.predicates().hasLanguage(Java.KEY), fs.predicates().hasType(type)));
}
private JavaVersion getJavaVersion() {
Optional<String> javaVersionAsString = settings.get(JavaVersion.SOURCE_VERSION);
if (!javaVersionAsString.isPresent()) {
return new JavaVersionImpl();
}
String enablePreviewAsString = settings.get(JavaVersion.ENABLE_PREVIEW).orElse("false");
JavaVersion javaVersion = JavaVersionImpl.fromStrings(javaVersionAsString.get(), enablePreviewAsString);
if (javaVersion.arePreviewFeaturesEnabled() && javaVersion.asInt() < JavaVersionImpl.MAX_SUPPORTED) {
LOG.warn("sonar.java.enablePreview is set but will be discarded as the Java version is less than the max" +
" supported version ({} < {})", javaVersion.asInt(), JavaVersionImpl.MAX_SUPPORTED);
javaVersion = new JavaVersionImpl(javaVersion.asInt(), false);
}
LOG.info("Configured Java source version ({}): {}, preview features enabled ({}): {}",
JavaVersion.SOURCE_VERSION, javaVersion.asInt(), JavaVersion.ENABLE_PREVIEW, javaVersion.arePreviewFeaturesEnabled());
return javaVersion;
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}

@ -27,6 +27,7 @@ public class JavaFileCheckRegistrar implements CheckRegistrar {
public void register(RegistrarContext registrarContext) {
// 调用 registerClassesForRepository 以将类与正确的存储库密钥相关联
registrarContext.registerClassesForRepository(JavaSecurityDesignRulesRepository.REPOSITORY_KEY, RulesList.getJavaRules(), Collections.emptyList());
registrarContext.registerClassesForRepository(JavaSecurityDesignRulesRepository.REPOSITORY_KEY + "-" + HtmlConstants.LANGUAGE_KEY, RulesList.getHtmlRules(), Collections.emptyList());
}
}

@ -6,6 +6,7 @@
*/
package com.keyware.sonar.java.rules;
import com.keyware.sonar.java.rules.checkers.SessionDateChecker;
import org.sonar.api.SonarEdition;
import org.sonar.api.SonarProduct;
import org.sonar.api.SonarQubeSide;

@ -42,9 +42,7 @@ public final class RulesList {
SystemFunctionChecker.class,
UploadFileVerifyChecker.class,
UpperCycleLimitRuleChecker.class,
UserStatusVerifyChecker.class,
HostIdentityChecker.class,
PasswordInputTagJavaChecker.class
UserStatusVerifyChecker.class
);
}
public static List<Class<? extends JavaCheck>> getHtmlRules() {

@ -8,6 +8,7 @@ package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.model.DefaultModuleScannerContext;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.ModuleScannerContext;
import org.sonar.plugins.java.api.internal.EndOfAnalysis;
@ -98,9 +99,10 @@ public class AuthenticationChecker extends IssuableSubscriptionVisitor implement
@Override
public void endOfAnalysis(ModuleScannerContext context) {
var defaultContext = (DefaultModuleScannerContext) context;
if (!isValidPathFound) {
System.out.println("应通过用户名口令、数据证书等其他手段对用户身份进行验证");
context.addIssueOnProject(this, "应通过用户名口令、数据证书等其他手段对用户身份进行验证");
defaultContext.addIssueOnProject(this, "应通过用户名口令、数据证书等其他手段对用户身份进行验证");
}
}
}

@ -30,7 +30,7 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor {
@Override
public List<Tree.Kind> nodesToVisit() {
return Arrays.asList(Tree.Kind.METHOD_INVOCATION, Tree.Kind.VARIABLE);
return Arrays.asList(Tree.Kind.METHOD_INVOCATION, Tree.Kind.VARIABLE, Tree.Kind.STRING_LITERAL);
}
@Override
@ -39,6 +39,8 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor {
visitMethodInvocation((MethodInvocationTree) tree);
} else if (tree.is(Tree.Kind.VARIABLE)) {
visitVariable((VariableTree) tree);
} else if (tree.is(Tree.Kind.STRING_LITERAL)) {
visitStringLiteral((LiteralTree) tree);
}
}
@ -92,12 +94,14 @@ public class CookieSensitiveParameterCheck extends IssuableSubscriptionVisitor {
System.out.println("Cookie参数设置中的value属性与局部变量一致: " + variableName);
reportIssue(expression, "Cookie参数设置中包含敏感字段");
}
} else if (expression.is(Tree.Kind.STRING_LITERAL)) {
String literalValue = LiteralTree.class.cast(expression).value();
if (containsSensitiveParam(literalValue)) {
System.out.println("Cookie参数设置中的name属性包含敏感字符串: " + literalValue);
reportIssue(expression, "Cookie参数设置中包含敏感字段");
}
}
}
private void visitStringLiteral(LiteralTree literalTree) {
String literalValue = literalTree.value();
if (containsSensitiveParam(literalValue)) {
System.out.println("Cookie参数设置中包含敏感字段: " + literalValue);
reportIssue(literalTree, "Cookie参数设置中包含敏感字段");
}
}

@ -37,24 +37,20 @@ public class DynamicCodeChecker extends IssuableSubscriptionVisitor {
MethodInvocationTree node = (MethodInvocationTree) tree;
var expressionTree = node.methodSelect();
if (expressionTree != null && expressionTree instanceof MemberSelectExpressionTree) {
if (expressionTree instanceof MemberSelectExpressionTree) {
var exprTree = (MemberSelectExpressionTree) expressionTree;
var name = exprTree.identifier();
if ("eval".equals(name.toString())) {
var varNameNode = exprTree.expression();
if (varNameNode != null && varNameNode instanceof IdentifierTree) {
if (varNameNode instanceof IdentifierTree) {
var varName = (IdentifierTree) varNameNode;
if (varName != null) {
var symbol = varName.symbol();
if (symbol != null) {
var varDecler = symbol.declaration();
if (varDecler != null && varDecler instanceof VariableTree) {
var variableTree = (VariableTree) varDecler;
var typeName = variableTree.type().toString();
if ("ScriptEngine".equals(typeName)) {
context.reportIssue(this, tree, "程序设计时禁止动态构建代码进行功能实现");
}
}
var symbol = varName.symbol();
var varDecler = symbol.declaration();
if (varDecler != null) {
var variableTree = (VariableTree) varDecler;
var typeName = variableTree.type().toString();
if ("ScriptEngine".equals(typeName)) {
context.reportIssue(this, tree, "程序设计时禁止动态构建代码进行功能实现");
}
}
}

@ -72,7 +72,7 @@ public class DynamicLibraryLoadChecker extends IssuableSubscriptionVisitor {
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
var methodSelect = tree.methodSelect();
if (methodSelect != null && methodSelect instanceof MemberSelectExpressionTree) {
if (methodSelect instanceof MemberSelectExpressionTree) {
var mset = (MemberSelectExpressionTree) methodSelect;
// 判断是否调用了System.loadLibrary()
if (mset.firstToken() != null && "System".equals(mset.firstToken().text()) && "loadLibrary".equals(mset.identifier().name())) {

@ -23,7 +23,7 @@ import java.util.List;
*/
@Rule(key = "FileCheck")
public class FileCheck extends IssuableSubscriptionVisitor {
private static final List<String> FILE_NAME_VARS = Arrays.asList("fileName", "fileExt", "fileSuffix", "fileEnd");
private static final List<String> FILE_NAME_VARS = Arrays.asList("fileName", "fileExt", "fileSuffix");
@Override
public List<Tree.Kind> nodesToVisit() {
@ -37,22 +37,20 @@ public class FileCheck extends IssuableSubscriptionVisitor {
ExpressionTree condition = ifStatement.condition();
// 在条件中检查文件名、文件扩展名或文件后缀的使用
IdenVisitor idenVisitor = new IdenVisitor();
condition.accept(idenVisitor);
if(idenVisitor.boo){
reportIssue(tree, "在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为");
}
checkVariableUsage(condition);
}
}
class IdenVisitor extends BaseTreeVisitor {
boolean boo = false;
@Override
public void visitIdentifier(IdentifierTree tree) {
if (FILE_NAME_VARS.contains(tree.name())) {
// 如果在条件中发现了文件名、文件扩展名或文件后缀的使用
boo = true;
private void checkVariableUsage(ExpressionTree condition) {
condition.accept(new BaseTreeVisitor() {
@Override
public void visitIdentifier(IdentifierTree tree) {
if (FILE_NAME_VARS.contains(tree.name())) {
// 如果在条件中发现了文件名、文件扩展名或文件后缀的使用,报告问题
System.out.println("依赖文件的名称或者扩展后缀:"+tree.name());
reportIssue(tree, "在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为");
}
}
}
});
}
}

@ -7,10 +7,14 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.declaration.VariableTreeImpl;
import org.sonar.java.model.expression.IdentifierTreeImpl;
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.tree.*;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
@ -34,13 +38,10 @@ public class HashSaltPassWordChecker extends IssuableSubscriptionVisitor {
}
@Override
public void visitNode(@Nonnull Tree tree) {
public void visitNode(Tree tree) {
MethodTree node = (MethodTree) tree;
var bodyVisitor = new MethodeBodyVisitor(this);
BlockTree block = node.block();
if(block != null){
block.accept(bodyVisitor);
}
node.block().accept(bodyVisitor);
}
@ -55,31 +56,34 @@ public class HashSaltPassWordChecker extends IssuableSubscriptionVisitor {
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
//获取到方法调用
// 获取到方法调用
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
// 获取到调用的方法
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if (expressionTree instanceof MemberSelectExpressionTreeImpl) {
// 获取到调用的方法
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
if ("setPassWord".equals(memberSelectExpressionTree.identifier().name())) {
Arguments arguments = tree.arguments();
for (ExpressionTree expressionTree1 : arguments) {
if (expressionTree1.is(Tree.Kind.IDENTIFIER)) {
IdentifierTree identifierTree = (IdentifierTree) expressionTree1;
// 判断set中使用的参数
if(!identifierTree.name().equals(strPassWord)){
checker.context.reportIssue(checker, identifierTree, "应使用盐值计算口令");
Tree parent = tree.arguments();
if (parent instanceof ArgumentListTreeImpl) {
for (ExpressionTree expressionTree1 : (ArgumentListTreeImpl) parent) {
if (expressionTree1 instanceof IdentifierTreeImpl) {
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree1;
// 判断set中使用的参数
if(!identifierTree.name().equals(strPassWord)){
checker.context.reportIssue(checker, identifierTree, "应使用盐值计算口令");
}
}else {
checker.context.reportIssue(checker, expressionTree1, "应使用盐值计算口令");
}
} else {
checker.context.reportIssue(checker, expressionTree1, "应使用盐值计算口令");
}
}
} else if("BCrypt".equals(memberSelectExpressionTree.expression().toString()) && "hashpw".equals(memberSelectExpressionTree.identifier().name())){
// 判断是否是生成的加盐后的密码
}else if("BCrypt".equals(memberSelectExpressionTree.expression().toString()) && "hashpw".equals(memberSelectExpressionTree.identifier().name())){
Tree parent = memberSelectExpressionTree.parent();
if(parent != null && parent instanceof MethodInvocationTree){
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) parent;
if(parent instanceof MethodInvocationTreeImpl){
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) parent;
Tree parent1 = methodInvocationTree.parent();
if(parent1 != null && parent1 instanceof VariableTree){
VariableTree variableTree = (VariableTree) parent1;
if(parent1 instanceof VariableTreeImpl){
VariableTreeImpl variableTree = (VariableTreeImpl) parent1;
// 加盐后的参数名称
strPassWord = variableTree.simpleName().name();
}
@ -87,17 +91,5 @@ public class HashSaltPassWordChecker extends IssuableSubscriptionVisitor {
}
}
}
@Override
public void visitNewClass(NewClassTree classTree) {
// 判断是否为RedirectView,如果是,则判断是否有参数,如果有参数,则判断参数的类型是否由方法传递进来的
String name = classTree.identifier().toString();
if ("PBEKeySpec".equals(name)) {
if (classTree.arguments().size() < 2) {
// 获取第一个参数语法树节点
checker.context.reportIssue(checker, classTree, "应使用盐值计算口令");
}
}
}
}
}

@ -1,80 +0,0 @@
/*
* 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.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import java.util.Collections;
import java.util.List;
/**
* 通过用户名口令数据证书等其他手段对主机身份进行鉴别
*
* @author RenFengJiang
* @date 2024/7/3
*/
@Rule(key = "HostIdentityChecker")
public class HostIdentityChecker extends IssuableSubscriptionVisitor {
@Override
public List<Tree.Kind> nodesToVisit() {
return Collections.singletonList(Tree.Kind.METHOD);
}
@Override
public void visitNode(Tree tree) {
MethodTree methodTree = (MethodTree) tree;
List<VariableTree> parameters = methodTree.parameters();
// 盘带是否是文件上传类
boolean boo = parameters.stream().anyMatch(type -> "HttpServletRequest".equals(type.type().toString()));
if(boo){
NodeIf nodeIf = new NodeIf();
methodTree.block().accept(nodeIf);
if(nodeIf.getNameBoolean() || nodeIf.getPasswordBoolean()){
context.reportIssue(this,methodTree.simpleName(),"通过用户名口令、数据证书等其他手段对主机身份进行鉴别");
}
}
}
public class NodeIf extends BaseTreeVisitor {
public boolean nameBoolean = true;
private boolean passwordBoolean = true;
boolean getNameBoolean(){
return nameBoolean;
}
boolean getPasswordBoolean(){
return passwordBoolean;
}
@Override
public void visitIfStatement(IfStatementTree tree) {
//获取到if表达式
ExpressionTree condition = tree.condition();
if (condition != null && condition instanceof BinaryExpressionTree) {
BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) condition;
//判断是否进行if判断
if ("username".equals(binaryExpressionTree.leftOperand().toString())) {
nameBoolean = false;
} else if ("password".equals(binaryExpressionTree.rightOperand().toString())) {
passwordBoolean = false;
}
}
if (condition != null && condition instanceof IdentifierTree) {
IdentifierTree identifierTree = (IdentifierTree) condition;
//判断是否进行if判断
if ("username".equals(identifierTree.name())) {
nameBoolean = false;
} else if ("password".equals(identifierTree.name())) {
passwordBoolean = false;
}
}
}
}
}

@ -7,11 +7,15 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.expression.BinaryExpressionTreeImpl;
import org.sonar.java.model.expression.IdentifierTreeImpl;
import org.sonar.java.model.expression.LiteralTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -50,12 +54,12 @@ public class HttpInputDataChecker extends IssuableSubscriptionVisitor {
@Override
public void visitIfStatement(IfStatementTree tree) {
ExpressionTree condition = tree.condition();
if (condition.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO)) {
BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) condition;
for (Tree operand : Arrays.asList(binaryExpressionTree.leftOperand(), binaryExpressionTree.rightOperand())) {
if (operand.is(Tree.Kind.IDENTIFIER)) {
IdentifierTree identifierTree = (IdentifierTree) operand;
if (condition instanceof BinaryExpressionTreeImpl) {
BinaryExpressionTreeImpl binaryExpressionTree = (BinaryExpressionTreeImpl) condition;
List<Tree> children = binaryExpressionTree.children();
for (Tree child:children) {
if(child instanceof IdentifierTreeImpl){
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) child;
list.add(identifierTree.name());
}
}
@ -65,20 +69,24 @@ public class HttpInputDataChecker extends IssuableSubscriptionVisitor {
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if ("setHeader".equals(memberSelectExpressionTree.identifier().name())
|| "addHeader".equals(memberSelectExpressionTree.identifier().name())) {
if(expressionTree instanceof MemberSelectExpressionTreeImpl){
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
if("setHeader".equals(memberSelectExpressionTree.identifier().name()) || "addHeader".equals(memberSelectExpressionTree.identifier().name())){
Arguments arguments = tree.arguments();
for (ExpressionTree argument : arguments) {
if(argument.is(Tree.Kind.STRING_LITERAL)){
checker.context.reportIssue(checker, argument, "HTTP输入数据验证");
break;
} else if(argument.is(Tree.Kind.IDENTIFIER)){
IdentifierTree identifierTree = (IdentifierTree) argument;
if(!list.contains(identifierTree.name())){
checker.context.reportIssue(checker, identifierTree, "HTTP输入数据验证");
break;
if(arguments instanceof ArgumentListTreeImpl){
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) {
if(argument instanceof LiteralTreeImpl){
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument;
if("STRING_LITERAL".equals(literalTree.kind().name())){
checker.context.reportIssue(checker, literalTree, "HTTP输入数据验证");
break;
}
}else if(argument instanceof IdentifierTreeImpl){
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) argument;
if(!list.contains(identifierTree.name())){
checker.context.reportIssue(checker, identifierTree, "HTTP输入数据验证");
break;
}
}
}
}

@ -7,6 +7,9 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.expression.IdentifierTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
@ -61,17 +64,19 @@ public class InputSQLVerifyChecker extends IssuableSubscriptionVisitor {
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if ("prepareStatement".equals(memberSelectExpressionTree.identifier().name()) || "executeQuery".equals(memberSelectExpressionTree.identifier().name())) {
if(expressionTree instanceof MemberSelectExpressionTreeImpl){
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
if("prepareStatement".equals(memberSelectExpressionTree.identifier().name())){
Arguments arguments = tree.arguments();
for (ExpressionTree argument : arguments) {
if (argument.is(Tree.Kind.IDENTIFIER)) {
IdentifierTree identifierTree = (IdentifierTree) argument;
String name = identifierTree.name();
// 判断使用的sql是否存在集合中
if (!lists.contains(name)) {
checker.context.reportIssue(checker, argument, "使用sql语句前应对其进行验证");
if(arguments instanceof ArgumentListTreeImpl){
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) {
if (argument instanceof IdentifierTreeImpl){
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) argument;
String name = identifierTree.name();
//判断使用的sql是否存在集合中
if(!lists.contains(name)){
checker.context.reportIssue(checker,argument,"使用sql语句前应对其进行验证");
}
}
}
}

@ -7,6 +7,11 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.declaration.VariableTreeImpl;
import org.sonar.java.model.expression.IdentifierTreeImpl;
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.tree.*;
@ -36,10 +41,7 @@ public class Md5PassWordVerifyChecker extends IssuableSubscriptionVisitor {
public void visitNode(Tree tree) {
MethodTree node = (MethodTree) tree;
var bodyVisitor = new MethodeBodyVisitor(this);
BlockTree block = node.block();
if(block != null){
block.accept(bodyVisitor);
}
node.block().accept(bodyVisitor);
}
@ -56,48 +58,36 @@ public class Md5PassWordVerifyChecker extends IssuableSubscriptionVisitor {
public void visitMethodInvocation(MethodInvocationTree tree) {
//获取到方法调用
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if (expressionTree instanceof MemberSelectExpressionTreeImpl) {
//获取到调用的方法
MemberSelectExpressionTreeImpl memberSelectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
if ("setPassWord".equals(memberSelectExpressionTree.identifier().name())) {
Arguments arguments = tree.arguments();
//改用arguments,这里没必要再用 instanceof 检查接口了
for (ExpressionTree argument : arguments) {
if (argument.is(Tree.Kind.IDENTIFIER)) {
IdentifierTree identifierTree = (IdentifierTree) argument;
String name = identifierTree.name();
if (!name.equals(strPassWord)) {
checker.context.reportIssue(checker, identifierTree, "应使用单向不可逆的加密算法");
Tree parent = tree.arguments();
if (parent instanceof ArgumentListTreeImpl) {
for (ExpressionTree expressionTree1 : (ArgumentListTreeImpl) parent) {
if (expressionTree1 instanceof IdentifierTreeImpl) {
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree1;
//判断set中使用的参数
if(!identifierTree.name().equals(strPassWord)){
checker.context.reportIssue(checker, identifierTree, "应使用单向不可逆的加密算法");
}
}else {
checker.context.reportIssue(checker, expressionTree1, "应使用单向不可逆的加密算法");
}
} else {
checker.context.reportIssue(checker, argument, "应使用单向不可逆的加密算法");
}
}
} else if (memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("md5hex")
|| memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("encrypt")) {
//判断是否使用单向不可逆加密方式
}else if(memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("md5hex") || memberSelectExpressionTree.identifier().name().toLowerCase(Locale.ROOT).contains("encrypt")){
Tree parent = memberSelectExpressionTree.parent();
//对parent进行了instanceof检查,这是不正确的,应该使用is(Tree.Kind.SOMETHING)
if (parent.is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) parent;
if(parent instanceof MethodInvocationTreeImpl){
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) parent;
Tree parent1 = methodInvocationTree.parent();
//这同样是对parent1进行了instanceof检查,这是不正确的,应该使用is(Tree.Kind.SOMETHING)
if (parent1.is(Tree.Kind.VARIABLE)) {
VariableTree variableTree = (VariableTree) parent1;
if(parent1 instanceof VariableTreeImpl){
VariableTreeImpl variableTree = (VariableTreeImpl) parent1;
//获取加密后的名称
strPassWord = variableTree.simpleName().name();
}
}
}else if ("Cipher".equals(memberSelectExpressionTree.expression().toString()) && "getInstance".equals(memberSelectExpressionTree.identifier().name())) {
// 获取参数列表
List<ExpressionTree> arguments = tree.arguments();
for (ExpressionTree argument : arguments) {
if (argument.is(Tree.Kind.STRING_LITERAL)) {
LiteralTree literalTree = (LiteralTree) argument;
String c = ((LiteralTree) argument).token().text();
// 对参数进行判断判断是否符合要求
if (literalTree.token().text().startsWith("\"AES")) {
checker.context.reportIssue(checker, argument, "应使用单向不可逆的加密算法");
}
}
}
}
}
}

@ -8,8 +8,17 @@
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.tree.*;
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;
@ -23,59 +32,47 @@ import java.util.List;
* @date 2024/1/22
*/
@Rule(key = "OptionsVerifyChecker")
public class OptionsVerifyChecker extends IssuableSubscriptionVisitor {
public class OptionsVerifyChecker extends IssuableSubscriptionVisitor implements EndOfAnalysis {
private boolean boo = true;
@Override
public List<Tree.Kind> nodesToVisit() {
return Collections.singletonList(Tree.Kind.METHOD);
/**
* Tree.Kind.METHOD方法节点
* Tree.Kind.BLOCK方法的代码块节点
* Tree.Kind.METHOD_INVOCATION 方法的调用节点
*/
return Collections.singletonList(Tree.Kind.METHOD_INVOCATION);
}
@Override
public void visitNode(Tree tree) {
MethodTree node = (MethodTree) tree;
List<VariableTree> parameters = node.parameters();
//盘带是否是文件上传类
boolean booleanRestorn = parameters.stream().anyMatch(type -> "HttpServletResponse".equals(type.type().toString()));
if (booleanRestorn) {
MethodCall methodCall = new MethodCall();
node.block().accept(methodCall);
if (methodCall.getBooleanInner()) {
context.reportIssue(this, node.simpleName(), "应设置X-Frame-Options的值为deny");
}
}
DeclarationVerdict declarationVerdict = new DeclarationVerdict(node,this);
node.block().accept(declarationVerdict);
}
private class MethodCall extends BaseTreeVisitor {
private boolean booleanInner = true;
public boolean getBooleanInner() {
return booleanInner;
}
public void visitMethodInvocation(MethodInvocationTree tree) {
if (booleanInner) {
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree selectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if ("addHeader".equals(selectExpressionTree.identifier().name()) || "setHeader".equals(selectExpressionTree.identifier().name())) {
Arguments arguments = tree.arguments();
//判断项目是否配置
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 : arguments) {
if (argument.is(Tree.Kind.STRING_LITERAL)) {
String literalValue = ((LiteralTree) argument).value();
if ("\"X-Frame-Options\"".equals(literalValue)) {
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(literalValue) ||"\"deny\"".equals(literalValue)) {
}else if("\"DENY\"".equals(literalTree.token().text())){
two = true;
}
}
}
if (one && two) {
booleanInner = false;
if(one && two){
boo = false;
}
}
}
@ -83,30 +80,11 @@ public class OptionsVerifyChecker extends IssuableSubscriptionVisitor {
}
}
public class DeclarationVerdict extends BaseTreeVisitor {
private MethodTree node;
private OptionsVerifyChecker checker;
public DeclarationVerdict( MethodTree node,OptionsVerifyChecker checker){
this.node = node;
this.checker = checker;
}
@Override
public void visitVariable(VariableTree tree) {
IdentifierTree identifierTree = tree.simpleName();
TypeTree type = tree.type();
if(type != null && type instanceof IdentifierTree){
IdentifierTree fierTree = (IdentifierTree) type;
if("HttpServletResponse".equals(fierTree.name())){
MethodCall methodCall = new MethodCall();
node.block().accept(methodCall);
if (methodCall.getBooleanInner()) {
context.reportIssue(checker, identifierTree, "应设置X-Frame-Options的值为deny");
}
}
}
@Override
public void endOfAnalysis(ModuleScannerContext context) {
var defaultContext = (DefaultModuleScannerContext) context;
if(boo){
defaultContext.addIssueOnProject(this, "应设置X-Frame-Options的值为deny");
}
}
}

@ -1,85 +0,0 @@
/*
* 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.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import java.util.Collections;
import java.util.List;
/**
* 用户输入口令时应对口令域进行掩饰用户输入的每一个字符都应该以星号形式回显
*
* @author RenFengJiang
* @date 2024/7/3
*/
@Rule(key = "PasswordInputTagJavaChecker")
public class PasswordInputTagJavaChecker extends IssuableSubscriptionVisitor {
@Override
public List<Tree.Kind> nodesToVisit() {
/**
* Tree.Kind.METHOD方法节点
* Tree.Kind.BLOCK方法的代码块节点
* Tree.Kind.METHOD_INVOCATION 方法的调用节点
*/
return Collections.singletonList(Tree.Kind.BLOCK);
}
@Override
public void visitNode(Tree tree) {
BlockTree node = (BlockTree) tree;
MethodeBodyVisitor methodeBodyVisitor = new MethodeBodyVisitor(this, node);
node.accept(methodeBodyVisitor);
}
static class MethodeBodyVisitor extends BaseTreeVisitor {
private BlockTree blockTree;
private PasswordInputTagJavaChecker checker;
public MethodeBodyVisitor(PasswordInputTagJavaChecker checker, BlockTree blockTree){
this.checker = checker;
this.blockTree = blockTree;
}
@Override
public void visitNewClass(NewClassTree tree) {
String name = tree.identifier().toString();
if("JTextField".equals(name)){
MethodeCall methodeCall = new MethodeCall();
blockTree.accept(methodeCall);
if(methodeCall.getEchoBoolean()){
checker.context.reportIssue(checker, tree, "Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显");
}
}
}
}
static class MethodeCall extends BaseTreeVisitor {
//是否存在JTextField输入
private boolean echoBoolean = true;
public boolean getEchoBoolean() {
return echoBoolean;
}
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
//获取到方法调用
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if ("setEchoChar".equals(memberSelectExpressionTree.identifier().name())) {
echoBoolean = false;
}
}
}
}
}

@ -18,82 +18,66 @@ import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import java.util.*;
import java.util.stream.Collectors;
@Rule(key = "PasswordRegexCheck")
public class PasswordRegexCheck extends IssuableSubscriptionVisitor {
private static final String MATCHER_METHOD = "matcher";
private static final String PASSWORD_PARAMETER = "password";
@Override
public List<Tree.Kind> nodesToVisit() {
// 在这里,我们只考虑方法
return Collections.singletonList(Tree.Kind.METHOD);
}
@Override
public void visitNode(Tree tree) {
MethodTree method = (MethodTree) tree;
// 检查是否存在名为 “password”的参数
List<VariableTree> passwordParameters = method.parameters().stream()
.filter(param -> "password".equals(param.simpleName().name()))
.collect(Collectors.toList());
if (!passwordParameters.isEmpty()) {
// 确认参数 "password" 是否在正确的正则表达式之下被检查
boolean passwordIsCheckedWithRegex = passwordParameters.stream()
.anyMatch(param -> isPasswordValidatedWithRegex(method, param));
if (!passwordIsCheckedWithRegex) {
reportIssue(method.simpleName(), "未对口令进行复杂度验证");
}
if (tree.is(Tree.Kind.METHOD)) {
MethodTree methodTree = (MethodTree) tree;
checkPasswordValidation(methodTree);
}
}
private boolean isPasswordValidatedWithRegex(Tree tree, VariableTree passwordParameter) {
PasswordValidationVisitor visitor = new PasswordValidationVisitor(passwordParameter);
tree.accept(visitor);
return visitor.isPasswordValidated();
}
private static class PasswordValidationVisitor extends BaseTreeVisitor {
private final VariableTree passwordParameter;
private boolean passwordValidated = false;
PasswordValidationVisitor(VariableTree passwordParameter) {
this.passwordParameter = passwordParameter;
}
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
// 改变行为,查找是否存在匹配指定方法调用模式的表达式
if (isCorrectPasswordValidationMethod(tree)) {
passwordValidated = true;
private void checkPasswordValidation(MethodTree methodTree) {
boolean hasPasswordValidation = false;
for (StatementTree statement : methodTree.block().body()) {
if (statement.is(Tree.Kind.VARIABLE)) {
VariableTree variableTree = (VariableTree) statement;
if (variableTree.initializer() != null && variableTree.initializer().is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) variableTree.initializer();
String methodName = methodInvocationTree.methodSymbol().name();
if (MATCHER_METHOD.equals(methodName)) {
hasPasswordValidation = hasPasswordValidation || hasPasswordParameter(methodInvocationTree.arguments());
}
}
}
super.visitMethodInvocation(tree);
}
public boolean isPasswordValidated() {
return passwordValidated;
if (!hasPasswordValidation) {
//如果没有发现密码验证,报告问题
System.out.println("未对口令进行复杂度验证"+methodTree.simpleName());
reportIssue(methodTree.simpleName(), "未对口令进行复杂度验证");
}
}
private boolean isCorrectPasswordValidationMethod(MethodInvocationTree mit) {
if ("matches".equals(mit.methodSymbol().name())
&& mit.methodSelect().is(Tree.Kind.MEMBER_SELECT)
&& ((MemberSelectExpressionTree) mit.methodSelect()).identifier().name().equals("matcher")
&& ((MemberSelectExpressionTree) mit.methodSelect()).expression().is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree innerMit = (MethodInvocationTree) ((MemberSelectExpressionTree) mit.methodSelect()).expression();
if ("compile".equals(innerMit.methodSymbol().name())
&& innerMit.methodSelect().is(Tree.Kind.MEMBER_SELECT)
&& "Pattern".equals( ((MemberSelectExpressionTree)innerMit.methodSelect()).expression().toString())) {
// 需要确定参数中包含名为 'password' 的参数
List<VariableTree> arguments = mit.methodSymbol().declaration().parameters().stream().filter(param -> param.symbol().name().equals("password")).collect(Collectors.toList());
return (!arguments.isEmpty());
private boolean hasPasswordParameter(List<ExpressionTree> arguments) {
for (ExpressionTree argument : arguments) {
if (argument.is(Tree.Kind.IDENTIFIER)) {
IdentifierTree identifier = (IdentifierTree) argument;
if (PASSWORD_PARAMETER.equalsIgnoreCase(identifier.name())) {
//检查标识符是否有密码验证
return hasPasswordValidationInMethod(identifier.name());
}
}
return false;
}
return false;
}
private boolean hasPasswordValidationInMethod(String paramName) {
//参数名是'password',已经存在
return PASSWORD_PARAMETER.equalsIgnoreCase(paramName);
}
}

@ -7,11 +7,13 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.InternalSyntaxToken;
import org.sonar.java.model.expression.LiteralTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
@ -23,8 +25,6 @@ import java.util.List;
@Rule(key = "RSAEncryptionChecker")
public class RSAEncryptionChecker extends IssuableSubscriptionVisitor {
private List nameLists = new ArrayList();
@Override
public List<Tree.Kind> nodesToVisit() {
/**
@ -32,73 +32,39 @@ public class RSAEncryptionChecker extends IssuableSubscriptionVisitor {
* Tree.Kind.BLOCK方法的代码块节点
* Tree.Kind.METHOD_INVOCATION 方法的调用节点
*/
return Arrays.asList(Tree.Kind.METHOD_INVOCATION, Tree.Kind.CLASS);
return Collections.singletonList(Tree.Kind.METHOD_INVOCATION);
}
@Override
public void visitNode(Tree tree) {
if (tree.is(Tree.Kind.CLASS)) {
MethodBOdyVisitor methodBOdyVisitor = new MethodBOdyVisitor();
tree.accept(methodBOdyVisitor);
nameLists = methodBOdyVisitor.getNameLists();
} else if (tree.is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if (expressionTree != null) {
// 获取到方法调用
if (expressionTree instanceof MemberSelectExpressionTree) {
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
// 判断是否符合标准
String a = memberSelectExpressionTree.expression().toString();
String b = memberSelectExpressionTree.identifier().name();
if ("Cipher".equals(memberSelectExpressionTree.expression().toString()) && "getInstance".equals(memberSelectExpressionTree.identifier().name())) {
// 获取参数列表
List<ExpressionTree> arguments = methodInvocationTree.arguments();
for (ExpressionTree argument : arguments) {
if (argument.is(Tree.Kind.STRING_LITERAL)) {
LiteralTree literalTree = (LiteralTree) argument;
String c = ((LiteralTree) argument).token().text();
// 对参数进行判断判断是否符合要求
if (!literalTree.token().text().startsWith("\"RSA")) {
context.reportIssue(this, argument, "使用RSA最优加密填充");
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
ExpressionTree expressionTree = methodInvocationTree.methodSelect();
// 获取到方法调用
if(expressionTree instanceof MemberSelectExpressionTree){
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
// 判断是否符合标准
if("Cipher".equals(memberSelectExpressionTree.expression().toString()) && "getInstance".equals(memberSelectExpressionTree.identifier().name())){
// 获取参数列表
Arguments arguments = methodInvocationTree.arguments();
if(arguments instanceof ArgumentListTreeImpl){
// 获取到参数列表
ArgumentListTreeImpl argumentListTree = (ArgumentListTreeImpl) arguments;
for (ExpressionTree argument : argumentListTree) {
if(argument instanceof LiteralTreeImpl){
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument;
// 获取到其中的参数
SyntaxToken syntaxToken = literalTree.token();
if(syntaxToken instanceof InternalSyntaxToken){
InternalSyntaxToken internalSyntaxToken = (InternalSyntaxToken) syntaxToken;
// 对参数进行判断判断是否符合要求
if(!(internalSyntaxToken.text().startsWith("\"RSA") && internalSyntaxToken.text().contains("OAEPWithSHA-256AndMGF1Padding"))){
context.reportIssue(this,tree,"使用RSA最优加密填充");
}
} else if (!nameLists.equals(argument.toString())) {
context.reportIssue(this, argument, "使用RSA最优加密填充");
}
}
}
}
}
}
}
static class MethodBOdyVisitor extends BaseTreeVisitor {
private List nameLists = new ArrayList();
public MethodBOdyVisitor() {
}
public List getNameLists() {
return nameLists;
}
@Override
public void visitVariable(VariableTree tree) {
IdentifierTree identifierTree = tree.simpleName();
ExpressionTree initializer = tree.initializer();
if (identifierTree != null && initializer != null && initializer instanceof LiteralTree) {
LiteralTree literalTree = (LiteralTree) initializer;
if (literalTree.value().startsWith("\"RSA")) {
nameLists.add(identifierTree.name());
}
}
}
}
}

@ -11,7 +11,6 @@ import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -44,15 +43,6 @@ public class RedirectUrlChecker extends IssuableSubscriptionVisitor {
checkByStringType(block, parameters);
}
}
if(!parameters.isEmpty()){
for (VariableTree parameter : parameters) {
if("HttpServletResponse".equals(parameter.type().toString())){
String name = parameter.simpleName().name();
MethodeBodyVisitor methodeBodyVisitor = new MethodeBodyVisitor(this, name);
methodTree.block().accept(methodeBodyVisitor);
}
}
}
}
private void checkByStringType(BlockTree block, List<? extends VariableTree> methodParameters) {
@ -61,7 +51,7 @@ public class RedirectUrlChecker extends IssuableSubscriptionVisitor {
ReturnStatementTree rs = (ReturnStatementTree) statementTree;
ExpressionTree exprTree = rs.expression();
if (exprTree != null && !exprTree.is(Tree.Kind.STRING_LITERAL)) {
if (exprTree != null && exprTree instanceof BinaryExpressionTree) {
if (exprTree instanceof BinaryExpressionTree) {
BinaryExpressionTree bExprTree = (BinaryExpressionTree) exprTree;
if (bExprTree.is(Tree.Kind.PLUS) && bExprTree.leftOperand().is(Tree.Kind.STRING_LITERAL) && bExprTree.rightOperand().is(Tree.Kind.IDENTIFIER)) {
var identifierTree = (IdentifierTree) bExprTree.rightOperand();
@ -85,49 +75,6 @@ public class RedirectUrlChecker extends IssuableSubscriptionVisitor {
}
//判断HttpServletResponse类型重定向
static class MethodeBodyVisitor extends BaseTreeVisitor {
private final RedirectUrlChecker checker;
private String name ;
private List lists = new ArrayList<String>();
MethodeBodyVisitor(RedirectUrlChecker checker,String name){
this.checker = checker;
this.name = name;
}
@Override
public void visitIfStatement(IfStatementTree tree) {
ExpressionTree condition = tree.condition();
condition.accept(new BaseTreeVisitor(){
@Override
public void visitIdentifier(IdentifierTree tree) {
lists.add(tree.name());
}
});
}
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if ("sendRedirect".equals(memberSelectExpressionTree.identifier().name()) && name.equals(memberSelectExpressionTree.expression().toString())) {
Arguments arguments = tree.arguments();
for (ExpressionTree argument : arguments) {
if (argument.is(Tree.Kind.IDENTIFIER)) {
IdentifierTree identifierTree = (IdentifierTree) argument;
String paramName = identifierTree.name();
// 判断使用的sql是否存在集合中
if (!lists.contains(paramName)) {
checker.context.reportIssue(checker, argument, "在重定向前对输入数据进行验证");
}
}
}
}
}
}
}
/**
* 判断方法是否为public方法
*
@ -139,13 +86,13 @@ public class RedirectUrlChecker extends IssuableSubscriptionVisitor {
var hasMappingAnnotation = false;
for (ModifierTree modifier : methodTree.modifiers()) {
// 判断是否为公共方法
if (!isPublic && modifier != null && modifier instanceof ModifierKeywordTree) {
if (!isPublic && modifier instanceof ModifierKeywordTree) {
if (((ModifierKeywordTree) modifier).modifier() == Modifier.PUBLIC) {
isPublic = true;
}
}
// 判断是否包含Mapping注解
if (!hasMappingAnnotation && modifier != null && modifier instanceof AnnotationTree) {
if (!hasMappingAnnotation && modifier instanceof AnnotationTree) {
AnnotationTree annotationTree = (AnnotationTree) modifier;
if (annotationTree.annotationType() instanceof IdentifierTree) {
IdentifierTree identifierTree = (IdentifierTree) annotationTree.annotationType();
@ -189,7 +136,7 @@ public class RedirectUrlChecker extends IssuableSubscriptionVisitor {
@Override
public void visitMethodInvocation(MethodInvocationTree invocationTree) {
ExpressionTree expressionTree = invocationTree.methodSelect();
if (expressionTree != null && expressionTree instanceof MemberSelectExpressionTree) {
if (expressionTree instanceof MemberSelectExpressionTree) {
MemberSelectExpressionTree member = (MemberSelectExpressionTree) expressionTree;
if (member.expression().symbolType().is("org.springframework.web.servlet.view.RedirectView")
&& "setUrl".equals(member.identifier().name())) {
@ -201,7 +148,7 @@ public class RedirectUrlChecker extends IssuableSubscriptionVisitor {
private void checkArgs(ExpressionTree argNode, Tree tree) {
// 判断该语法树节点是否为IdentifierTree,如果是,则说明语法树节点为变量,然后判断该变量是否是包含在方法的参数列表中
if (argNode != null && argNode instanceof IdentifierTree) {
if (argNode instanceof IdentifierTree) {
IdentifierTree identifierTree = (IdentifierTree) argNode;
String argName = identifierTree.name();
if (methodParameters.stream().anyMatch(parameter -> parameter.simpleName().name().equals(argName))) {

@ -42,46 +42,44 @@ public class SecurityCookieChecker extends IssuableSubscriptionVisitor {
// 盘带是否是文件上传类
boolean boo = parameters.stream().anyMatch(type -> "HttpServletResponse".equals(type.type().toString()));
if(boo){
var bodyVisitor = new MethodBOdyVisitor();
var bodyVisitor = new MethodBOdyVisitor(this);
node.block().accept(bodyVisitor);
if(bodyVisitor.booCure){
context.reportIssue(this,node.simpleName(),"设置HTTPS会话中cookie的安全属性");
if(bodyVisitor.booHttp){
if(!(bodyVisitor.booAge && bodyVisitor.booCure)){
context.reportIssue(this,node.simpleName(),"设置HTTPS会话中cookie的安全属性");
}
}
// if(bodyVisitor.booHttp){
// if(!(bodyVisitor.booAge && bodyVisitor.booCure)){
// context.reportIssue(this,node.simpleName(),"设置HTTPS会话中cookie的安全属性");
// }
// }
}
}
static class MethodBOdyVisitor extends BaseTreeVisitor{
private final SecurityCookieChecker checker;
// 判断是否是https请求
private boolean booCure = true;
private boolean booCure = false;
// 设置cooker时长
// private boolean booAge = false;
private boolean booAge = false;
// 设置访问
// private boolean booHttp = false;
public MethodBOdyVisitor( ){
private boolean booHttp = false;
public MethodBOdyVisitor(SecurityCookieChecker checker ){
this.checker = checker;
}
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect();
if(expressionTree != null && expressionTree instanceof MemberSelectExpressionTree){
if(expressionTree instanceof MemberSelectExpressionTree){
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree;
switch (memberSelectExpressionTree.identifier().name()){
// case "setHttpOnly":
// booHttp = true;
// break;
case "setHttpOnly":
booHttp = true;
break;
case "setSecure":
booCure = false;
booCure = true;
break;
case "setMaxAge":
booAge = true;
break;
// case "setMaxAge":
// booAge = true;
// break;
}
}
}

@ -8,6 +8,9 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.model.expression.IdentifierTreeImpl;
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.tree.*;
@ -45,10 +48,10 @@ public class SendMessageVerifyChecker extends IssuableSubscriptionVisitor {
@Override
public void visitNode(Tree tree) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
MethodInvocationTreeImpl methodInvocationTree = (MethodInvocationTreeImpl) tree;
ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if(expressionTree.is(Tree.Kind.IDENTIFIER)){
IdentifierTree identifierTree = (IdentifierTree) expressionTree;
if(expressionTree instanceof IdentifierTreeImpl){
IdentifierTreeImpl identifierTree = (IdentifierTreeImpl) expressionTree;
//判断方法是否是方法调用的节点
if(identifierTree.name().toLowerCase().contains("send")){
IdenVisitor idenVisitor = new IdenVisitor(this);
@ -70,6 +73,7 @@ public class SendMessageVerifyChecker extends IssuableSubscriptionVisitor {
checker.context.reportIssue(checker, tree, "发送信息规则检查");
}
}
}
}

@ -7,9 +7,16 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.expression.LiteralTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Type;
import org.sonar.plugins.java.api.tree.*;
import org.sonar.plugins.java.api.tree.Arguments;
import org.sonar.plugins.java.api.tree.ExpressionTree;
import org.sonar.plugins.java.api.tree.MethodInvocationTree;
import org.sonar.plugins.java.api.tree.Tree;
import javax.annotation.Nonnull;
import java.util.List;
@ -29,10 +36,9 @@ public class SessionCacheParamsChecker extends IssuableSubscriptionVisitor {
"userid",
"token",
"url",
"userpassword",
"price"
"userpassword"
);
private static final String requestType = "HttpServletRequest";
private static final String requestType = "javax.servlet.http.HttpServletRequest";
@Override
public List<Tree.Kind> nodesToVisit() {
@ -41,32 +47,38 @@ public class SessionCacheParamsChecker extends IssuableSubscriptionVisitor {
@Override
public void visitNode(@Nonnull Tree tree) {
// ((MemberSelectExpressionTree)methodInvocationTree.methodSelect()).expression().symbolType()
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
//获取参数
ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if(expressionTree.is(Tree.Kind.MEMBER_SELECT)){
MemberSelectExpressionTree selectExpressionTree = (MemberSelectExpressionTree) expressionTree;
//获取参数类型
Type type = selectExpressionTree.expression().symbolType();
String fierName = selectExpressionTree.identifier().name();
if(type != null){
//判断参数类型和调用方法符不符合要求
if(type.fullyQualifiedName().contains(requestType)
&& ("getParameter".equals(fierName) || "getCookies".equals(fierName))) {
//如果是getCookies方法直接抛错
if("getCookies".equals(fierName)){
reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取");
}else {
//获取参数
Arguments arguments = methodInvocationTree.arguments();
for (ExpressionTree argument : arguments) {
if(argument.is(Tree.Kind.STRING_LITERAL)){
String name = ((LiteralTree) argument).value()
.replace("\"", "").toLowerCase();
//判断是否是违规项
if(HIDED_PARAMS.contains(name)){
reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取");
break;
Symbol.MethodSymbol methodSymbol = methodInvocationTree.methodSymbol();
if(methodSymbol.isMethodSymbol()) {
//获取参数
ExpressionTree expressionTree = methodInvocationTree.methodSelect();
if(expressionTree instanceof MemberSelectExpressionTreeImpl){
MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
//获取参数类型
Type type = selectExpressionTree.expression().symbolType();
if(type != null){
//判断参数类型和调用方法符不符合要求
if(requestType.equals(type.fullyQualifiedName())
&& ("getParameter".equals(methodSymbol.name()) || "getCookies".equals(methodSymbol.name()))) {
//如果是getCookies方法直接抛错
if("getCookies".equals(methodSymbol.name())){
reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取");
}else {
//获取参数
Arguments arguments = methodInvocationTree.arguments();
if(arguments instanceof ArgumentListTreeImpl){
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) {
if(argument instanceof LiteralTreeImpl){
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument;
//获取参数值
String name = literalTree.token().text().replace("\"", "").toLowerCase();
//判断是否是违规项
if(HIDED_PARAMS.contains(name)){
reportIssue(methodInvocationTree, "页面隐藏域字段、Cookie、URL等关键参数不能直接获取,应缓存到服务器端的会话中并通过会话获取");
break;
}
}
}
}
}

@ -27,7 +27,7 @@ import java.util.Scanner;
* @date 2024/1/22
*/
@Rule(key = "SessionDateChecker")
public class SessionDateCheckera implements ConfigCheck {
public class SessionDateChecker implements ConfigCheck {
private boolean boo = true;
public void execute(SensorContext context, InputFile inputFile, RuleKey ruleKey){
@ -77,7 +77,7 @@ public class SessionDateCheckera implements ConfigCheck {
Map<String, Object> currentLevel = map;
for (int i = 0; i < keys.length - 1; ++i) {
Object nextLevel = currentLevel.get(keys[i]);
if (nextLevel != null && nextLevel instanceof Map) {
if (nextLevel instanceof Map) {
currentLevel = (Map<String, Object>) nextLevel;
} else {
return null;

@ -37,9 +37,6 @@ public class UploadFileVerifyChecker extends IssuableSubscriptionVisitor {
@Override
public void visitNode(Tree tree) {
MethodTree node = (MethodTree) tree;
DeclarationVerdict declarationVerdict = new DeclarationVerdict(node,this);
((MethodTree) tree).block().accept(declarationVerdict);
List<VariableTree> parameters = node.parameters();
//盘带是否是文件上传类
boolean boo = parameters.stream().anyMatch(type -> "MultipartFile".equals(type.type().toString()));
@ -99,35 +96,35 @@ public class UploadFileVerifyChecker extends IssuableSubscriptionVisitor {
public void visitMethodInvocation(MethodInvocationTree tree) {
//获取到方法调用的参数
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree != null && expressionTree instanceof MemberSelectExpressionTree) {
if (expressionTree instanceof MemberSelectExpressionTree) {
MemberSelectExpressionTree expressionTree1 = (MemberSelectExpressionTree) expressionTree;
//对调用方法进行判断
if ("getOriginalFilename".equals(expressionTree1.identifier().toString())) {
Tree parent = expressionTree1.parent();
if (parent != null && parent instanceof MethodInvocationTree) {
if (parent instanceof MethodInvocationTree) {
MethodInvocationTree memberSelectExpressionTree = (MethodInvocationTree) parent;
Tree parent1 = memberSelectExpressionTree.parent();
if (parent1 != null && parent1 instanceof VariableTree) {
if (parent1 instanceof VariableTree) {
VariableTree variableTree = (VariableTree) parent1;
fileName = variableTree.simpleName().toString();
}
}
} else if ("extName".equals(expressionTree1.identifier().toString())) {
Tree parent = expressionTree1.parent();
if (parent != null && parent instanceof MethodInvocationTree) {
if (parent instanceof MethodInvocationTree) {
MethodInvocationTree memberSelectExpressionTree = (MethodInvocationTree) parent;
Tree parent1 = memberSelectExpressionTree.parent();
if (parent1 != null && parent1 instanceof VariableTree) {
if (parent1 instanceof VariableTree) {
VariableTree variableTree = (VariableTree) parent1;
fileType = variableTree.simpleName().toString();
}
}
} else if ("getSize".equals(expressionTree1.identifier().toString())) {
Tree parent = expressionTree1.parent();
if (parent != null && parent instanceof MethodInvocationTree) {
if (parent instanceof MethodInvocationTree) {
MethodInvocationTree memberSelectExpressionTree = (MethodInvocationTree) parent;
Tree parent1 = memberSelectExpressionTree.parent();
if (parent1 != null && parent1 instanceof VariableTree) {
if (parent1 instanceof VariableTree) {
VariableTree variableTree = (VariableTree) parent1;
sizeName = variableTree.simpleName().toString();
}
@ -142,10 +139,10 @@ public class UploadFileVerifyChecker extends IssuableSubscriptionVisitor {
public class NodeIf extends BaseTreeVisitor {
private Object name;
private String name;
public boolean boo = true;
public NodeIf(Object name) {
public NodeIf(String name) {
this.name = name;
}
@ -153,7 +150,7 @@ public class UploadFileVerifyChecker extends IssuableSubscriptionVisitor {
public void visitIfStatement(IfStatementTree tree) {
//获取到if表达式
ExpressionTree condition = tree.condition();
if (condition != null && condition instanceof BinaryExpressionTree) {
if (condition instanceof BinaryExpressionTree) {
BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) condition;
//判断是否进行if判断
if (name.equals(binaryExpressionTree.leftOperand().toString())) {
@ -162,42 +159,6 @@ public class UploadFileVerifyChecker extends IssuableSubscriptionVisitor {
boo = false;
}
}
if (condition != null && condition instanceof IdentifierTree) {
IdentifierTree identifierTree = (IdentifierTree) condition;
//判断是否进行if判断
if (name.equals(identifierTree.name())) {
boo = false;
} else if (name.equals(identifierTree.name())) {
boo = false;
}
}
}
}
public class DeclarationVerdict extends BaseTreeVisitor {
private MethodTree node;
private UploadFileVerifyChecker checker;
public DeclarationVerdict( MethodTree node,UploadFileVerifyChecker checker){
this.node = node;
this.checker = checker;
}
@Override
public void visitVariable(VariableTree tree) {
IdentifierTree identifierTree = tree.simpleName();
TypeTree type = tree.type();
if(type != null && type instanceof IdentifierTree){
IdentifierTree fierTree = (IdentifierTree) type;
if("Fileltem".equals(fierTree.name())){
NodeIf nodeIf = new NodeIf(identifierTree.name());
node.block().accept(nodeIf);
if (nodeIf.boo) {
context.reportIssue(checker, identifierTree, value);
}
}
}
}
}
}

@ -7,6 +7,7 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.model.expression.BinaryExpressionTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
@ -31,9 +32,7 @@ public class UpperCycleLimitRuleChecker extends IssuableSubscriptionVisitor {
MethodTree methodTree = (MethodTree) tree;
List<VariableTree> args = methodTree.parameters();
BlockTree blockTree = methodTree.block();
if(blockTree != null){
blockTree.accept(new MethodBlockVisitor(this, args));
}
blockTree.accept(new MethodBlockVisitor(this, args));
}
@ -48,39 +47,32 @@ public class UpperCycleLimitRuleChecker extends IssuableSubscriptionVisitor {
@Override
public void visitForStatement(ForStatementTree fnode) {
ExpressionTree ffnode = fnode.condition();
if (ffnode.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO, Tree.Kind.LESS_THAN, Tree.Kind.LESS_THAN_OR_EQUAL_TO, Tree.Kind.GREATER_THAN, Tree.Kind.GREATER_THAN_OR_EQUAL_TO)) {
BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) ffnode;
ExpressionTree leftOperand = binaryExpressionTree.leftOperand();
var ffnode = fnode.condition();
if (ffnode instanceof BinaryExpressionTreeImpl) {
ExpressionTree leftOperand = ((BinaryExpressionTreeImpl) ffnode).leftOperand();
checkVar(leftOperand);
ExpressionTree rightOperand = binaryExpressionTree.rightOperand();
ExpressionTree rightOperand = ((BinaryExpressionTreeImpl) ffnode).rightOperand();
checkVar(rightOperand);
}
}
@Override
public void visitWhileStatement(WhileStatementTree wnode) {
ExpressionTree wwnode = wnode.condition();
if (wwnode.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO, Tree.Kind.LESS_THAN, Tree.Kind.LESS_THAN_OR_EQUAL_TO, Tree.Kind.GREATER_THAN, Tree.Kind.GREATER_THAN_OR_EQUAL_TO)) {
BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) wwnode;
ExpressionTree leftOperand = binaryExpressionTree.leftOperand();
checkVar(leftOperand);
}
var wwnode = wnode.condition();
ExpressionTree teea = ((BinaryExpressionTreeImpl) wwnode).leftOperand();
checkVar(teea);
}
@Override
public void visitDoWhileStatement(DoWhileStatementTree dnode) {
ExpressionTree ddnode = dnode.condition();
if (ddnode.is(Tree.Kind.EQUAL_TO, Tree.Kind.NOT_EQUAL_TO, Tree.Kind.LESS_THAN, Tree.Kind.LESS_THAN_OR_EQUAL_TO, Tree.Kind.GREATER_THAN, Tree.Kind.GREATER_THAN_OR_EQUAL_TO)) {
BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) ddnode;
ExpressionTree leftOperand = binaryExpressionTree.leftOperand();
checkVar(leftOperand);
}
var ddnode = dnode.condition();
ExpressionTree teeas = ((BinaryExpressionTreeImpl) ddnode).leftOperand();
checkVar(teeas);
}
private void checkVar(ExpressionTree operand) {
if (operand != null && operand instanceof IdentifierTree) {
if (operand instanceof IdentifierTree) {
IdentifierTree identifierTree = (IdentifierTree) operand;
var name = identifierTree.name();
for (VariableTree varTree : args) {

@ -8,6 +8,10 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.ast.parser.ArgumentListTreeImpl;
import org.sonar.java.model.declaration.VariableTreeImpl;
import org.sonar.java.model.expression.LiteralTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
@ -32,16 +36,15 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor {
MethodTree methodTree = (MethodTree) tree;
//判断是否是doFilter或doFilter方法
boolean boo = verifyMethod(methodTree);
if (boo) {
if(boo){
//内部实现类
VisitMethod visitMethod = new VisitMethod(this);
//调用内部实现类
methodTree.block().accept(visitMethod);
//判断是否满足4个条件
if (visitMethod.booOne && visitMethod.booTwo && visitMethod.booThree && visitMethod.booFour) {
if(visitMethod.booOne && visitMethod.booTwo && visitMethod.booThree && visitMethod.booFour){
} else {
System.out.println(methodTree.simpleName());
}else{
context.reportIssue(this, methodTree.simpleName(), "对用户进行身份鉴别并建立一个新的会话时让原来的会话失效");
}
@ -50,15 +53,19 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor {
public static boolean verifyMethod(MethodTree methodTree) {
//preHandle
// if ("doFilter".equals(methodTree.simpleName().name()) || "preHandle".equals(methodTree.simpleName().name())) {
//获取参数
List<VariableTree> parameters = methodTree.parameters();
for (VariableTree variable : parameters) {
if (variable.type().symbolType().name().endsWith("ServletRequest")) {
return true;
if ("doFilter".equals(methodTree.simpleName().name()) || "preHandle".equals(methodTree.simpleName().name())) {
//获取参数
List<VariableTree> parameters = methodTree.parameters();
for (VariableTree variable : parameters) {
if (variable instanceof VariableTreeImpl) {
//判断参数是否有ServletRequest
VariableTreeImpl variableTree = (VariableTreeImpl) variable;
if (variableTree.type().toString().endsWith("ServletRequest")) {
return true;
}
}
}
}
//}
return false;
}
@ -79,31 +86,33 @@ public class UserStatusVerifyChecker extends IssuableSubscriptionVisitor {
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
ExpressionTree expressionTree = tree.methodSelect();
if (expressionTree.is(Tree.Kind.MEMBER_SELECT)) {
if(expressionTree instanceof MemberSelectExpressionTreeImpl){
//判断是否调用指定的方法
MemberSelectExpressionTree selectExpressionTree = (MemberSelectExpressionTree) expressionTree;
if ("getParameter".equals(selectExpressionTree.identifier().name()) || "getSession".equals(selectExpressionTree.identifier().name())) {
MemberSelectExpressionTreeImpl selectExpressionTree = (MemberSelectExpressionTreeImpl) expressionTree;
if("getParameter".equals(selectExpressionTree.identifier().name()) || "getSession".equals(selectExpressionTree.identifier().name())){
//获取到调用方法的参数
Arguments arguments = tree.arguments();
//调用判断参数的方法
verifyParam(arguments);
} else if ("invalidate".equals(selectExpressionTree.identifier().name())) {
}else if ("invalidate".equals(selectExpressionTree.identifier().name())){
booFour = true;
}
}
}
public void verifyParam(Arguments arguments) {
for (ExpressionTree argument : arguments) {
if (argument.is(Tree.Kind.STRING_LITERAL)) {
LiteralTree literalTree = (LiteralTree) argument;
String strName = literalTree.value().replace("\"", "").toLowerCase();
if ("username".equals(strName)) {
booOne = true;
} else if ("password".equals(strName)) {
booTwo = true;
} else if ("false".equals(strName)) {
booThree = true;
public void verifyParam(Arguments arguments){
if(arguments instanceof ArgumentListTreeImpl){
for (ExpressionTree argument : (ArgumentListTreeImpl) arguments) {
if(argument instanceof LiteralTreeImpl){
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument;
String strName = literalTree.token().text().replace("\"", "").toLowerCase();
if("username".equals(strName)){
booOne = true;
}else if("password".equals(strName)){
booTwo = true;
}else if("false".equals(strName)){
booThree = true;
}
}
}
}

@ -1,5 +1,5 @@
<p>通过用户名口令、数据证书等其他手段对用户身份进行验证</p>
<h2>通过用户名口令、数据证书等其他手段对用户身份进行验证</h2>
<p>通过用户名口令、数据证书等其他手段对用户身份进行验证</p>
<h2>通过用户名口令、数据证书等其他手段对用户身份进行验证</h2>
<pre>
</pre>

@ -1,5 +1,5 @@
{
"title": "通过用户名口令、数据证书等其他手段对用户身份进行验证",
"title": "通过用户名口令、数据证书等其他手段对用户身份进行验证",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {

@ -1,16 +0,0 @@
<!--
~ Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
~ 项目名称:信息安全性设计准则检查插件
~ 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件
~ 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
-->
<p>通过用户名口令、数据证书等其他手段对主机身份进行鉴别</p>
<h2>通过用户名口令、数据证书等其他手段对主机身份进行鉴别</h2>
<pre>
</pre>
<h2>合规解决方案</h2>
<pre>
</pre>

@ -1,13 +0,0 @@
{
"title": "通过用户名口令、数据证书等其他手段对主机身份进行鉴别",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"28suo"
],
"defaultSeverity": "Minor"
}

@ -1,16 +0,0 @@
<!--
~ Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
~ 项目名称:信息安全性设计准则检查插件
~ 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件
~ 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
-->
<h2>Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显</h2>
<p>Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显</p>
<pre>
</pre>
<h2>合规解决方案</h2>
<pre>
</pre>

@ -1,13 +0,0 @@
{
"title": "Java用户输入口令时应对口令域进行掩饰,用户输入的每一个字符都应该以星号形式回显",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "15min"
},
"tags": [
"28suo"
],
"defaultSeverity": "Major"
}

@ -1,33 +0,0 @@
{
"name": "Sonar way",
"ruleKeys": [
"ABCVarNameChecker",
"AbsolutePathDetectorChecker",
"AuthenticationChecker",
"AvoidSensitiveInfoInLogsCheck",
"ConfigurationFileChecker",
"CookieSensitiveParameterCheck",
"DynamicCodeChecker",
"DynamicLibraryLoadChecker",
"ErrorMessageChecker",
"FileCheck",
"HashSaltPassWordChecker",
"HttpInputDataChecker",
"InputSQLVerifyChecker",
"Md5PassWordVerifyChecker",
"OptionsVerifyChecker",
"PasswordInputTagChecker",
"PasswordRegexCheck",
"PathAndKeywordCheck",
"RedirectUrlChecker",
"RSAEncryptionChecker",
"SecurityCookieChecker",
"SendMessageVerifyChecker",
"SessionCacheParamsChecker",
"SessionDateChecker",
"SystemFunctionChecker",
"UploadFileVerifyChecker",
"UpperCycleLimitRuleChecker",
"UserStatusVerifyChecker"
]
}

@ -1,38 +1,22 @@
public class FileCheck {
public class FileCheck{
public String FileName() {
public String FileName(){
String fileName = "";
String fileExt = "";
String fileSuffix = "";
if (fileName.endsWith("png")) {// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
if(fileName.endsWith("png") ){// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
}
if (fileExt.equals("jpg")) {// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
if(fileExt.equals("jpg") ){// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
}
if (fileSuffix.equals("jpg")) {// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
if(fileSuffix.equals("jpg")){// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
}
return null;
}
public void imageBeauty(HttpServletRequest request) { //处理图像文件
DiskFileltemFactory factory = new DiskFileltemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
Iterator<Fileltem> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
String fileName = item.getName();
String fileEnd = fileName.substring(fileName.lastlndexOf(".") + 1).toLowerCase();
//依赖文件扩展名进行验证
if (fileEnd != null && fileEnd.matches(regex)) {// Noncompliant {{在服务器端不允许仅仅依赖文件的名称或者扩展后缀决定软件的行为,应依赖文件的内容决定软件的行为}}
//对文件的相关操作
}
}
}
}

@ -1,7 +1,7 @@
public class HashSaltPassWordRule {
public static void cs(Student student) {
public static void cs(Student student){
// 结合盐值和口令进行散列计算
// String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
@ -29,22 +29,4 @@ public class HashSaltPassWordRule {
}
}
public class Example {
private String encrypt(String password, KeySpec key) { //加密函数,返回加密后的字符串
MessageDigest md = MessageDigest.getInstance("SHA-256");
}
public void storePassword(String password) {
byte[] salt = new byte[length];
Random random = new SecureRandom();
random.nextBytes(salt);//随机生成盐值
// 使用盐值生成密钥KeySpec key = new PBEKeySpec(password.toCharArray(),salt,iterationCount);
// KeySpec keyspec = new PBEKeySpec(ssword.toCharArray(),salt,iterationCount);//生成密钥
KeySpec keyspec = new PBEKeySpec(ssword.toCharArray());// Noncompliant {{应使用盐值计算口令}}
//仅使用单向加密,还是容易被攻击者用彩虹表等方式破解口令
String encryptedPassword = encrypt(password, key);
//将 encryptedPassword 存放到数据库
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save