修复:根据测试提供结果,修改C++规则漏报误报

master
RenFengJiang 2 months ago
parent d302ca7340
commit dc9b749c56
  1. 98
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxSquidSensor.java
  2. 16
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.java
  3. 10
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/CmdDataVerifyChecker.java
  4. 114
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.java
  5. 6
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.java
  6. 2
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.java
  7. 13
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRShaChecker.java
  8. 20
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.java
  9. 12
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/HighEncryptDesChecker.java
  10. 12
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.java
  11. 20
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyChecker.java
  12. 67
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountChecker.java
  13. 105
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.java
  14. 38
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyChecker.java
  15. 44
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.java
  16. 92
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.java
  17. 39
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ValidatePasswordCheck.java
  18. 59
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathChecker.java
  19. 2
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.java
  20. 5
      sonar-keyware-plugins-cxx/src/main/java/org/sonar/cxx/squidbridge/AstScanner.java
  21. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/BufferDataCheckerTest.java
  22. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyCheckerTest.java
  23. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmCheckerTest.java
  24. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/FileAccessCheckerTest.java
  25. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyCheckerTest.java
  26. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyCheckerTest.java
  27. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountCheckerTest.java
  28. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyCheckerTest.java
  29. 3
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyCheckerTest.java
  30. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SendMessageCheckerTest.java
  31. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordCheckerTest.java
  32. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathCheckerTest.java
  33. 1
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageCheckerTest.java
  34. 14
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.cc
  35. 6
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.cc
  36. 2
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.cc
  37. 7
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.cc
  38. 3
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.cc
  39. 9
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.cc
  40. 4
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyChecker.cc
  41. 26
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/PassWordCountChecker.cc
  42. 24
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.cc
  43. 58
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/SQLVerifyChecker.cc
  44. 2
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.cc
  45. 14
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.cc
  46. 2
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/VerificationPathChecker.cc
  47. 1
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.cc
  48. 4
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java
  49. 2
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java
  50. 2
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java
  51. 3
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordInputTagJavaChecker.java
  52. 2
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java
  53. 1
      sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java
  54. 3
      sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java

@ -308,17 +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
@ -514,7 +513,7 @@ public class CxxSquidSensor implements ProjectSensor {
newIssue.at(location);
newIssue.save();
}catch (Exception e){
} catch (Exception e) {
LOG.error("save issue error, rule key: {}", message);
}
} else {
@ -553,23 +552,28 @@ public class CxxSquidSensor implements ProjectSensor {
// measures for the lines of file
var fileLinesContext = fileLinesContextFactory.createFor(inputFile);
List<Integer> linesOfCode = (List<Integer>) sourceCode.getData(CxxMetric.NCLOC_DATA);
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);
}
});
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);
}
});
}
List<Integer> executableLines = (List<Integer>) sourceCode.getData(CxxMetric.EXECUTABLE_LINES_DATA);
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);
}
});
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);
}
});
}
fileLinesContext.save();
}
@ -580,15 +584,18 @@ public class CxxSquidSensor implements ProjectSensor {
NewCpdTokens cpdTokens = context.newCpdTokens().onFile(inputFile);
List<CxxCpdVisitor.CpdToken> data = (List<CxxCpdVisitor.CpdToken>) sourceCode.getData(CxxMetric.CPD_TOKENS_DATA);
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);
}
});
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);
}
});
}
cpdTokens.save();
}
@ -601,16 +608,19 @@ public class CxxSquidSensor implements ProjectSensor {
List<CxxHighlighterVisitor.Highlight> data = (List<CxxHighlighterVisitor.Highlight>) sourceCode.getData(
CxxMetric.HIGHLIGTHING_DATA);
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);
}
});
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);
}
});
}
newHighlighting.save();
}

@ -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)){
if("memcpy".equals(name) || "strncpy".equals(name) || "memset".equals(name) || "strcpy".equals(name)){
//判断方法参数是否进行校验
List<AstNode> astNodeList = ast.getDescendants(CxxGrammarImpl.initializerList);
AstNode astNode = astNodeList.get(astNodeList.size() - 1);
@ -101,6 +101,20 @@ 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,12 +72,13 @@ public class CmdDataVerifyChecker extends SquidCheck<Grammar> {
//判断节点是不是if节点
if("if".equals(astNode.getToken().getValue())){
//获取其中的参数
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList);
astNodeList.addAll(astNode.getDescendants(CxxGrammarImpl.condition));
for (AstNode expr:astNodeList) {
List<AstNode> descendants = astNode.getDescendants(CxxGrammarImpl.condition);
// List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList);
// astNodeList.addAll(astNode.getDescendants(CxxGrammarImpl.condition));
for (AstNode expr:descendants) {
lists.add(expr.getToken().getValue());
}
if(astNodeList.size() == 0){
if(descendants.size() == 0){
List<AstNode> astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression);
for (AstNode as:astNodes) {
List<AstNode> children = as.getChildren();
@ -94,6 +95,7 @@ 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,6 +32,7 @@ import java.util.Map;
public class DLLVerifyChecker extends SquidCheck<Grammar> {
private static String name = "在动态加载库前对输入数据进行验证";
@Override
public void init() {
// 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点
@ -48,101 +49,86 @@ public class DLLVerifyChecker extends SquidCheck<Grammar> {
@Override
public void visitNode(@Nonnull AstNode node) {
Map<String, Integer> map = ifParam(node);
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);
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);
}
}
}
//判断是否是dlopen格式的动态加载库
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);
}
}
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);
}
} else {
getContext().createLineViolation(this, name, dren);
}
}
}
}
}
//对LoadLibrary格式的动态加载库进行校验
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;
}
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;
}
}else {
getContext().createLineViolation(this,name,firstDescendant);
} else {
getContext().createLineViolation(this, name, desc);
break;
}
}
} 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());
}
}
}

@ -53,7 +53,7 @@ public class EncryptionAlgorithmChecker extends SquidCheck<Grammar> {
var callNode = next.getFirstDescendant(CxxGrammarImpl.postfixExpression);
if(callNode != null){
var callList = callNode.getDescendants(CxxGrammarImpl.className);
if(!callList.isEmpty()) {
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-> {
@ -69,7 +69,11 @@ public class EncryptionAlgorithmChecker extends SquidCheck<Grammar> {
cache.values().forEach(item->{
getContext().createLineViolation(this, "特定字段未使用单向加密算法对口令进行加密并存储", item);
});
}else if(astNode.getTokenValue().contains("AESEncryption") ){
getContext().createLineViolation(this, "特定字段未使用单向加密算法对口令进行加密并存储", astNode);
}
}
String tokenValue = astNode.getTokenValue();
}
}

@ -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")){
if(str.contains("openssl/aes.h") || str.contains("openssl/des.h") || str.contains("\"aes.h\"")){
getContext().createFileViolation(this, "应使用单向不可逆算法对密码进行加密");
break;
}

@ -41,14 +41,13 @@ 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("openssl/") || str.contains("cryptopp/") ){
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("sha.h") && !str.contains("blake2.h") && !str.contains("md5.h")) {
getContext().createFileViolation(this, "应使用不可逆标准散列算法");
break;
}
}
}
}

@ -18,6 +18,7 @@ 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;
@ -39,6 +40,7 @@ public class FileAccessChecker extends SquidCheck<Grammar> {
public void init() {
subscribeTo(CxxGrammarImpl.selectionStatement);
subscribeTo(CxxGrammarImpl.declaration);
subscribeTo(CxxGrammarImpl.postfixExpression);
conditionVariables = new HashSet<>();
}
@ -49,9 +51,27 @@ public class FileAccessChecker extends SquidCheck<Grammar> {
} 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);
}
}
}
}
}
}
private void handleDeclaration(AstNode node) {
AstNode ifstreamNode = findIfstreamNode(node);

@ -41,13 +41,11 @@ 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("openssl/") || str.contains("cryptopp/") ){
if(!str.contains("aes.h") && !str.contains("des.h") ){
getContext().createFileViolation(this, "应采用加密强度较高的标准加密算法");
break;
}
for (String str : inputFileLines) {
if (str.startsWith("#include")) {
if (str.contains("des.h") || str.contains("blake2.h")) {
getContext().createFileViolation(this, "应采用加密强度较高的标准加密算法");
break;
}
}
}

@ -117,6 +117,18 @@ public class IntegerCountVerifyChecker extends SquidCheck<Grammar> {
}
}
}
}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;

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

@ -51,7 +51,7 @@ public class PassWordCountChecker extends SquidCheck<Grammar> {
bodyWay.accept(astNode);
}
class BodyWay extends SubscriptionAstVisitor{
class BodyWay extends SubscriptionAstVisitor {
/**
* 构造函数需要传入初代访问器
@ -72,45 +72,78 @@ 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){
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());
}
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());
}
}
}
}
//判断生成的散列值参数是否是进行赋后的入参
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,7 +6,9 @@
*/
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;
@ -16,6 +18,7 @@ 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;
@ -37,7 +40,7 @@ public class PathVerifyChecker extends SquidCheck<Grammar> {
public void init() {
// 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点
this.subscribeTo(
CxxGrammarImpl.declarationStatement
CxxGrammarImpl.functionBody
);
}
@ -48,23 +51,9 @@ public class PathVerifyChecker extends SquidCheck<Grammar> {
*/
@Override
public void visitNode(@Nonnull AstNode node) {
//获取参数
AstNode firstDescendant = node.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)){
getContext().createLineViolation(this, "使用关键资源时指定资源所在的路径", chil);
}
}
}
}
}
IfBuffer ifBuffer = new IfBuffer(this);
ifBuffer.accept(node);
}
//判断是不是路径
@ -91,4 +80,84 @@ 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, "使用关键资源时指定资源所在的路径");
}
}
}
}
}
}
}
}

@ -54,6 +54,7 @@ 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);
}
@ -99,6 +100,43 @@ 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,10 +36,16 @@ 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");
}};
@ -54,20 +60,38 @@ 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);
List<AstNode> children = firstDescendant.getChildren();
AstNode astNode = children.get(2);
//判断其中的参数类型
if("STRING".equals(astNode.getName())){
if (children != null) {
AstNode astNode = children.get(0);
//判断其中的参数类型
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);
}
}
}
}

@ -17,6 +17,7 @@ import org.sonar.cxx.squidbridge.checks.SquidCheck;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -36,47 +37,78 @@ public class UserInputPasswordChecker extends SquidCheck<Grammar> {
@Override
public void init() {
subscribeTo(CxxGrammarImpl.functionBody);
subscribeTo(CxxGrammarImpl.simpleDeclaration);
}
@Override
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);
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);
}
}
}
}
}
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

@ -15,6 +15,7 @@ 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;
/**
@ -28,7 +29,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
@ -38,17 +39,33 @@ public class ValidatePasswordCheck extends SquidCheck<Grammar> {
@Override
public void visitNode(AstNode astNode) {
VerdictPassword(astNode);
checkPasswordValidationInMain(astNode);
AstNode functionNameNode = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId);
if(functionNameNode != null){
String functionName = functionNameNode.getTokenValue();
}
//检查函数是否为main
if ("main".equals(functionName)) {
checkPasswordValidationInMain(astNode);
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());
}
}
}
}
}
}
private void checkPasswordValidationInMain(AstNode mainFunctionNode) {
@ -64,7 +81,7 @@ public class ValidatePasswordCheck extends SquidCheck<Grammar> {
String variableName = declaratorId.getTokenValue();
// 检查变量是否命名为password
if ("password".equalsIgnoreCase(variableName)) {
if (variableName.toLowerCase().contains("password")) {
checkPasswordInitialization(initDeclarator);
}
}
@ -88,6 +105,10 @@ public class ValidatePasswordCheck extends SquidCheck<Grammar> {
getContext().createLineViolation(this, "口令不匹配足够复杂度", initializationValue);
}
}
} else {
if (!lists.contains(declaration.getTokenValue())) {
getContext().createLineViolation(this, "口令不匹配足够复杂度", declaration);
}
}
}

@ -22,6 +22,9 @@ import java.io.FileReader;
import java.io.IOException;
import java.util.List;
/**
* 在构建路径名前对输入数据进行验证确保外部输入仅包含允许的构成路径名的字符
*/
@Rule(key = "VerificationPathChecker", name = "在构建路径名前对数据进行校验", description = "对输入数据进行校验", priority = Priority.INFO, tags = {"28suo"})
@ActivatedByDefault
@ -40,6 +43,62 @@ public class VerificationPathChecker extends SquidCheck<Grammar> {
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) {

@ -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");
private List<String> keywords = Arrays.asList("add", "keyword2", "keyword3","password","name","type","token","username");
private Map<String, Map<String, AstNode>> caches = new HashMap<>();
@Override

@ -1,10 +1,9 @@
/*
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved.
* 项目名称信息安全性设计准则检查插件
* 项目描述用于检查源代码的安全性设计准则的Sonarqube插件
* 项目名称28所 C++ 信息安全性设计准则
* 项目描述用于检查C++源代码的安全性设计准则的Sonarqube插件
* 版权说明本软件属北京关键科技股份有限公司所有在未获得北京关键科技股份有限公司正式授权情况下任何企业和个人不能获取阅读安装传播本软件涉及的任何受知识产权保护的内容
*/
package org.sonar.cxx.squidbridge; // cxx: in use
import static com.google.common.base.Preconditions.checkNotNull;

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

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

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

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

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

@ -28,7 +28,8 @@ 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(26).withMessage("在使用SQL语句前对输入数据进行验证")
.next().atLine(5).withMessage("在使用SQL语句前对输入数据进行验证")
.noMore();
}
}

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

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

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

@ -32,6 +32,7 @@ public class VirtualLockUsageCheckerTest {
.next().atLine(8).withMessage("特定字段未使用VirtualLock()函数锁定存放敏感信息的内存")
.next().atLine(10).withMessage("特定字段未使用VirtualLock()函数锁定存放敏感信息的内存")
.next().atLine(12).withMessage("特定字段未使用VirtualLock()函数锁定存放敏感信息的内存")
.next().atLine(14).withMessage("特定字段未使用VirtualLock()函数锁定存放敏感信息的内存")
.noMore();
}
}

@ -60,4 +60,16 @@ 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,4 +75,10 @@ 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,5 +1,6 @@
#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,
@ -31,4 +32,10 @@ int main() {
// ... 然后可以进一步处理密文 ...
return 0;
}
int encryptor(char* input,char* output)//加密函数,输出参数返回加密后的字符串
{
AESEncryption aesEncryptor;
int r= aesEncryptor.enc(input,output);//使用双向可逆的 AES加密算法
}

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

@ -11,4 +11,13 @@ 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();
}
}

@ -14,5 +14,9 @@ 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,4 +17,28 @@ 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,4 +5,28 @@ 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,53 +1,7 @@
#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;
#include<stdio.h>
#include<string.h>
void sqlQuery(char * name){
char sqlQuery[64] = "select * from cus where userid=";
strcat(sqlQuery,name);
strcat(sqlQuery,"'");
}

@ -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,4 +46,18 @@ 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++;
}
}

@ -9,7 +9,7 @@ void verifyPath(const string& path);
int main(){
string userPath;
cin >> userPath;
strcat(path,filename);
// 在获取用户输入之后立即对其进行验证
// checkPath(userPath);
// verifyPath(userPath);

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

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

@ -7,9 +7,7 @@
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.MethodInvocationTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;

@ -10,8 +10,6 @@ package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.model.expression.IdentifierTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.ModuleScannerContext;
import org.sonar.plugins.java.api.internal.EndOfAnalysis;
import org.sonar.plugins.java.api.tree.*;
import java.util.Collections;

@ -8,15 +8,12 @@
package com.keyware.sonar.java.rules.checkers;
import org.sonar.check.Rule;
import org.sonar.java.model.expression.NewClassTreeImpl;
import org.sonar.java.model.statement.BlockTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.tree.*;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/**
* 用户输入口令时应对口令域进行掩饰用户输入的每一个字符都应该以星号形式回显

@ -7,14 +7,12 @@
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.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;
/**

@ -7,7 +7,6 @@
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.*;

@ -11,9 +11,6 @@ import com.keyware.sonar.java.utils.FilesUtils;
import org.junit.jupiter.api.Test;
import org.sonar.java.checks.verifier.CheckVerifier;
import java.util.ArrayList;
import java.util.Collection;
/**
* TODO OptionsVerifyCheckerTest
*

Loading…
Cancel
Save