From dc9b749c563750957762e427853800b88c1adad5 Mon Sep 17 00:00:00 2001 From: RenFengJiang <1111> Date: Wed, 10 Jul 2024 19:10:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=8F=90=E4=BE=9B=E7=BB=93=E6=9E=9C=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9C++=E8=A7=84=E5=88=99=E6=BC=8F=E6=8A=A5?= =?UTF-8?q?=E8=AF=AF=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/keyware/sonar/cxx/CxxSquidSensor.java | 98 ++++++++------- .../cxx/rules/checkers/BufferDataChecker.java | 16 ++- .../rules/checkers/CmdDataVerifyChecker.java | 10 +- .../cxx/rules/checkers/DLLVerifyChecker.java | 114 ++++++++---------- .../checkers/EncryptionAlgorithmChecker.java | 6 +- .../rules/checkers/FVNRPassWordChecker.java | 2 +- .../cxx/rules/checkers/FVNRShaChecker.java | 13 +- .../cxx/rules/checkers/FileAccessChecker.java | 20 +++ .../rules/checkers/HighEncryptDesChecker.java | 12 +- .../checkers/IntegerCountVerifyChecker.java | 12 ++ .../cxx/rules/checkers/PRNGVerifyChecker.java | 20 ++- .../rules/checkers/PassWordCountChecker.java | 67 +++++++--- .../cxx/rules/checkers/PathVerifyChecker.java | 105 +++++++++++++--- .../cxx/rules/checkers/SQLVerifyChecker.java | 38 ++++++ .../rules/checkers/SendMessageChecker.java | 44 +++++-- .../checkers/UserInputPasswordChecker.java | 92 +++++++++----- .../rules/checkers/ValidatePasswordCheck.java | 39 ++++-- .../checkers/VerificationPathChecker.java | 59 +++++++++ .../checkers/VirtualLockUsageChecker.java | 2 +- .../org/sonar/cxx/squidbridge/AstScanner.java | 5 +- .../rules/checkers/BufferDataCheckerTest.java | 2 + .../rules/checkers/DLLVerifyCheckerTest.java | 1 + .../EncryptionAlgorithmCheckerTest.java | 1 + .../rules/checkers/FileAccessCheckerTest.java | 1 + .../IntegerCountVerifyCheckerTest.java | 1 + .../rules/checkers/PRNGVerifyCheckerTest.java | 1 + .../checkers/PassWordCountCheckerTest.java | 2 + .../rules/checkers/PathVerifyCheckerTest.java | 2 + .../rules/checkers/SQLVerifyCheckerTest.java | 3 +- .../checkers/SendMessageCheckerTest.java | 1 + .../UserInputPasswordCheckerTest.java | 1 + .../checkers/VerificationPathCheckerTest.java | 1 + .../checkers/VirtualLockUsageCheckerTest.java | 1 + .../cxx/rules/checkers/BufferDataChecker.cc | 14 ++- .../cxx/rules/checkers/DLLVerifyChecker.cc | 6 + .../checkers/EncryptionAlgorithmChecker.cc | 2 +- .../cxx/rules/checkers/FVNRPassWordChecker.cc | 7 ++ .../cxx/rules/checkers/FileAccessChecker.cc | 3 + .../checkers/IntegerCountVerifyChecker.cc | 9 ++ .../cxx/rules/checkers/PRNGVerifyChecker.cc | 4 + .../rules/checkers/PassWordCountChecker.cc | 26 +++- .../cxx/rules/checkers/PathVerifyChecker.cc | 24 ++++ .../cxx/rules/checkers/SQLVerifyChecker.cc | 58 +-------- .../cxx/rules/checkers/SendMessageChecker.cc | 2 +- .../checkers/UserInputPasswordChecker.cc | 14 +++ .../rules/checkers/VerificationPathChecker.cc | 2 +- .../rules/checkers/VirtualLockUsageChecker.cc | 1 + .../keyware/sonar/java/rules/RulesList.java | 4 +- .../checkers/HashSaltPassWordChecker.java | 2 - .../rules/checkers/OptionsVerifyChecker.java | 2 - .../checkers/PasswordInputTagJavaChecker.java | 3 - .../rules/checkers/RSAEncryptionChecker.java | 2 - .../checkers/UpperCycleLimitRuleChecker.java | 1 - .../checkers/OptionsVerifyCheckerTest.java | 3 - 54 files changed, 687 insertions(+), 294 deletions(-) diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxSquidSensor.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxSquidSensor.java index b5f3b12..b299eef 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxSquidSensor.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/CxxSquidSensor.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 inputFiles = getInputFiles(context, squidConfig); - scanner.scanInputFiles(inputFiles); + Iterable inputFiles = getInputFiles(context, squidConfig); + scanner.scanInputFiles(inputFiles); - Collection squidSourceFiles = scanner.getIndex().search(); - save(squidSourceFiles); + Collection 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 linesOfCode = (List) 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 executableLines = (List) 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 data = (List) 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 data = (List) 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(); } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.java index 5a01543..d18f62f 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.java @@ -92,7 +92,7 @@ public class BufferDataChecker extends SquidCheck { 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 astNodeList = ast.getDescendants(CxxGrammarImpl.initializerList); AstNode astNode = astNodeList.get(astNodeList.size() - 1); @@ -101,6 +101,20 @@ public class BufferDataChecker extends SquidCheck { if(!lists.contains(tokenValue)){ reportIssue(ast, "应对读写缓冲区的数据长度进行检查"); } + }else if("scanf".equals(name)){ + List astNodeList = ast.getDescendants(CxxGrammarImpl.initializerList); + if(astNodeList != null){ + AstNode astNode = astNodeList.get(astNodeList.size() - 1); + List childrens = astNode.getChildren(); + if(childrens.size() != 0){ + String tokenValue = childrens.get(0).getTokenValue(); + boolean boo = tokenValue.chars().anyMatch(Character::isDigit); + if(!boo){ + reportIssue(ast, "应对读写缓冲区的数据长度进行检查"); + } + } + } + } } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/CmdDataVerifyChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/CmdDataVerifyChecker.java index 83e5d0d..afafea2 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/CmdDataVerifyChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/CmdDataVerifyChecker.java @@ -72,12 +72,13 @@ public class CmdDataVerifyChecker extends SquidCheck { //判断节点是不是if节点 if("if".equals(astNode.getToken().getValue())){ //获取其中的参数 - List astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList); - astNodeList.addAll(astNode.getDescendants(CxxGrammarImpl.condition)); - for (AstNode expr:astNodeList) { + List descendants = astNode.getDescendants(CxxGrammarImpl.condition); +// List 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 astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression); for (AstNode as:astNodes) { List children = as.getChildren(); @@ -94,6 +95,7 @@ public class CmdDataVerifyChecker extends SquidCheck { String name = ast.getParent().getToken().getValue(); //判断是否时使用sanitizeString方法 if("system".equals(name)){ + String valueName = ast.getToken().getValue(); //判断方法参数是否进行校验 if(!lists.contains(ast.getToken().getValue())){ reportIssue(ast, "在构建命令前对输入数据进行验证"); diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.java index 75181d4..a6c29cb 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.java @@ -32,6 +32,7 @@ import java.util.Map; public class DLLVerifyChecker extends SquidCheck { private static String name = "在动态加载库前对输入数据进行验证"; + @Override public void init() { // 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点 @@ -48,101 +49,86 @@ public class DLLVerifyChecker extends SquidCheck { @Override public void visitNode(@Nonnull AstNode node) { Map map = ifParam(node); - List 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 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 map,AstNode simp){ - //获取方法名 - List 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 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 map, AstNode simp) { + //获取其中的参数列表 + AstNode firstDescendant = simp.getFirstDescendant(CxxGrammarImpl.expressionList); + if (firstDescendant != null) { + List 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 map,AstNode simp){ - //获取方法名 - AstNode firstDescendant = simp.getFirstDescendant(CxxGrammarImpl.postfixExpression); - if(firstDescendant != null){ - if("LoadLibrary".equals(firstDescendant.getTokenValue())){ - //获取其中的参数列表 - List 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 map, AstNode simp) { + List 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 ifParam(AstNode node){ + public static Map ifParam(AstNode node) { Map map = new HashMap<>(); //选择节点语句 List 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 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 astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression); - for (AstNode as:astNodes) { + for (AstNode as : astNodes) { List children = as.getChildren(); - for (AstNode chil:children) { - map.put(chil.getTokenValue(),chil.getTokenLine()); + for (AstNode chil : children) { + map.put(chil.getTokenValue(), chil.getTokenLine()); } } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.java index bf931e7..883983e 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.java @@ -53,7 +53,7 @@ public class EncryptionAlgorithmChecker extends SquidCheck { 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 { cache.values().forEach(item->{ getContext().createLineViolation(this, "特定字段未使用单向加密算法对口令进行加密并存储", item); }); + }else if(astNode.getTokenValue().contains("AESEncryption") ){ + getContext().createLineViolation(this, "特定字段未使用单向加密算法对口令进行加密并存储", astNode); + } } + String tokenValue = astNode.getTokenValue(); } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.java index 5371b87..45099fe 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.java @@ -43,7 +43,7 @@ public class FVNRPassWordChecker extends SquidCheck { List 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; } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRShaChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRShaChecker.java index cd133eb..cc470f7 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRShaChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FVNRShaChecker.java @@ -41,14 +41,13 @@ public class FVNRShaChecker extends SquidCheck { public void visitFile(@Nullable AstNode astNode) { //逐行获取内容 List 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; } + } } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.java index b12fa6b..998e5b9 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.java @@ -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 { public void init() { subscribeTo(CxxGrammarImpl.selectionStatement); subscribeTo(CxxGrammarImpl.declaration); + subscribeTo(CxxGrammarImpl.postfixExpression); conditionVariables = new HashSet<>(); } @@ -49,9 +51,27 @@ public class FileAccessChecker extends SquidCheck { } 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 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); diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/HighEncryptDesChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/HighEncryptDesChecker.java index a060d26..17b43c2 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/HighEncryptDesChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/HighEncryptDesChecker.java @@ -41,13 +41,11 @@ public class HighEncryptDesChecker extends SquidCheck { public void visitFile(@Nullable AstNode astNode) { //逐行获取内容 List 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; } } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.java index 73ea15c..a01655e 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.java @@ -117,6 +117,18 @@ public class IntegerCountVerifyChecker extends SquidCheck { } } } + }else { + List 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; diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyChecker.java index e0d3b20..538e9a9 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyChecker.java @@ -33,9 +33,12 @@ public class PRNGVerifyChecker extends SquidCheck { @Override public void init() { // 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点 - this.subscribeTo( + subscribeTo( CxxGrammarImpl.declarationStatement ); + subscribeTo( + CxxGrammarImpl.postfixExpression + ); } /** @@ -45,13 +48,20 @@ public class PRNGVerifyChecker extends SquidCheck { */ @Override public void visitNode(@Nonnull AstNode node) { - List 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 descendants = node.getDescendants(CxxGrammarImpl.typeName); + for (AstNode desc:descendants) { + if(lists.contains(desc.getTokenValue())){ + getContext().createLineViolation(this, "应使用目前被业界专家认为较强的经过良好审核的加密PRNG算法", node); + break; + } } } + } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountChecker.java index 4315468..7acaf8e 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountChecker.java @@ -51,7 +51,7 @@ public class PassWordCountChecker extends SquidCheck { bodyWay.accept(astNode); } - class BodyWay extends SubscriptionAstVisitor{ + class BodyWay extends SubscriptionAstVisitor { /** * 构造函数需要传入初代访问器 @@ -72,45 +72,78 @@ public class PassWordCountChecker extends SquidCheck { //获取方法参数列表 List nodeDescendants = astNode.getDescendants(CxxGrammarImpl.expressionList); List seqLists = new ArrayList<>(); - for(AstNode desc :nodeDescendants){ + for (AstNode desc : nodeDescendants) { seqLists.add(desc.getTokenValue()); } //判读入参有没有进行赋值操作 List astNodes = astNode.getDescendants(CxxGrammarImpl.assignmentExpression); List 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 lists = new ArrayList<>(); List astNodeDescendants = astNode.getDescendants(CxxGrammarImpl.simpleDeclaration); - for(AstNode des :astNodeDescendants){ - if("std".equals(des.getTokenValue())){ - List descendants = des.getDescendants(CxxGrammarImpl.typeName); - for (AstNode dan : descendants){ - if("hash".equals(dan.getTokenValue())){ - List nodeList = des.getDescendants(CxxGrammarImpl.initDeclarator); - for (AstNode lis:nodeList) { - lists.add(lis.getTokenValue()); - } + for (AstNode des : astNodeDescendants) { + List descendants = des.getDescendants(CxxGrammarImpl.typeName); + for (AstNode dan : descendants) { + if ("hash".equals(dan.getTokenValue())) { + List nodeList = des.getDescendants(CxxGrammarImpl.initDeclarator); + for (AstNode lis : nodeList) { + lists.add(lis.getTokenValue()); } } } + } //判断生成的散列值参数是否是进行赋后的入参 List descendants = astNode.getDescendants(CxxGrammarImpl.postfixExpression); - for (AstNode desc:descendants) { - if(lists.contains(desc.getTokenValue())){ + for (AstNode desc : descendants) { + if (lists.contains(desc.getTokenValue())) { List 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 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 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 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, "使用盐值计算散列值"); + } + } + } } } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.java index 11d4dbc..a717c9f 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyChecker.java @@ -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 { public void init() { // 指定当前访问器需要访问的节点类型,functionBody(函数)主体节点 this.subscribeTo( - CxxGrammarImpl.declarationStatement + CxxGrammarImpl.functionBody ); } @@ -48,23 +51,9 @@ public class PathVerifyChecker extends SquidCheck { */ @Override public void visitNode(@Nonnull AstNode node) { - //获取参数 - AstNode firstDescendant = node.getFirstDescendant(CxxGrammarImpl.initializer); - if (firstDescendant!=null){ - List 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 { return matcher.find(); // 使用find()而不是matches(),因为matches()要求整个字符串都符合模式 } + + class IfBuffer extends SubscriptionAstVisitor { + + List lists = new ArrayList(); + + public IfBuffer(SquidCheck checker) { + super(checker); + } + + @Override + public List visitNodeTypes() { + // 指定当前访问器需要访问的节点类型,这里指定了simpleDeclaration(简单声明)节点类型 + return List.of(CxxGrammarImpl.functionBody); + } + + @Override + public void visitNode(@Nonnull AstNode node) { + //选择节点语句 + List nodeDescendants = node.getDescendants(CxxGrammarImpl.selectionStatement); + for (AstNode astNode : nodeDescendants) { + //判断节点是不是if节点 + if ("if".equals(astNode.getToken().getValue())) { + //获取其中的参数 + List astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList); + for (AstNode expr : astNodeList) { + lists.add(expr.getToken().getValue()); + } + + if (astNodeList.size() == 0) { + List astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression); + for (AstNode as : astNodes) { + List children = as.getChildren(); + for (AstNode chil : children) { + lists.add(chil.getTokenValue()); + } + } + } + } + } + + List astNodes = node.getDescendants(CxxGrammarImpl.declarationStatement); + if (astNodes !=null && !astNodes.isEmpty()) { + for (AstNode astNode : astNodes) { + //获取参数 + AstNode firstDescendant = astNode.getFirstDescendant(CxxGrammarImpl.initializer); + if (firstDescendant != null) { + List 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 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 childrens = descendant.getChildren(); + if (childrens != null && !childrens.isEmpty()) { + String tokenValue = childrens.get(0).getTokenValue(); + if (tokenValue != null && !lists.equals(tokenValue)) { + reportIssue(descendant, "使用关键资源时指定资源所在的路径"); + } + } + } + } + } + } + } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyChecker.java index e3d3a4e..b915884 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyChecker.java @@ -54,6 +54,7 @@ public class SQLVerifyChecker extends SquidCheck { class IfSQL extends SubscriptionAstVisitor{ List lists = new ArrayList(); + List names = new ArrayList(); public IfSQL(SquidCheck checker){ super(checker); } @@ -99,6 +100,43 @@ public class SQLVerifyChecker extends SquidCheck { } } } + List 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 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 astNodeList = descendant.getDescendants(CxxGrammarImpl.initializerList); + boolean booValue = false; + for(AstNode astNode : astNodeList){ + List 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; + } + } + } + } + } + } + } } + } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.java index a6d3a81..9fc0d94 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.java @@ -36,10 +36,16 @@ public class SendMessageChecker extends SquidCheck { CxxGrammarImpl.functionBody ); } - private static List lists = new ArrayList(){{ + + private static List 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 { //获取到所有的表达式 List 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 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 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); + } } } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.java index 84b22ae..82c48ac 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.java @@ -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 { @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 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 children = descendant.getChildren(); + for(AstNode chil : children){ + if("\'*\'".contains(chil.getTokenValue())){ + booPut = false; + } + } } - next = next.getNextAstNode(); - } while (next != null); + } } + } + + + + + - }); } @Override diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ValidatePasswordCheck.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ValidatePasswordCheck.java index 38bb48d..8dfa62e 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ValidatePasswordCheck.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/ValidatePasswordCheck.java @@ -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 { - + 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 { @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 nodeDescendants = node.getDescendants(CxxGrammarImpl.selectionStatement); + for (AstNode astNode : nodeDescendants) { + //判断节点是不是if节点 + if ("if".equals(astNode.getToken().getValue())) { + //获取其中的参数 + List astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList); + for (AstNode expr : astNodeList) { + lists.add(expr.getToken().getValue()); + } + if (astNodeList.size() == 0) { + List astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression); + for (AstNode as : astNodes) { + List 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 { 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 { getContext().createLineViolation(this, "口令不匹配足够复杂度", initializationValue); } } + } else { + if (!lists.contains(declaration.getTokenValue())) { + getContext().createLineViolation(this, "口令不匹配足够复杂度", declaration); + } } } diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathChecker.java index 0515cfa..d0452df 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathChecker.java @@ -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 { break; } } + MethodJudge(astNode); + } + + //方法拼接判断 + private void MethodJudge(AstNode node){ + boolean boo = true; + List nodeDescendants = node.getDescendants(CxxGrammarImpl.selectionStatement); + for (AstNode astNode : nodeDescendants) { + //判断节点是不是if节点 + if ("if".equals(astNode.getToken().getValue())) { + //获取其中的参数 + List astNodeList = astNode.getDescendants(CxxGrammarImpl.expressionList); + for (AstNode expr : astNodeList) { + if(expr.getTokenValue().toLowerCase().equals("filename")){ + boo = false; + break; + } + } + + if (astNodeList.size() == 0) { + List astNodes = astNode.getDescendants(CxxGrammarImpl.relationalExpression); + for (AstNode as : astNodes) { + List children = as.getChildren(); + for (AstNode chil : children) { + if(chil.getTokenValue().toLowerCase().equals("filename")){ + boo = false; + break; + } + } + } + } + } + } + + List 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 astNodeList = descendant.getDescendants(CxxGrammarImpl.initializerList); + for(AstNode astNode : astNodeList){ + List 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) { diff --git a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.java b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.java index 3fb8013..db5b0eb 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.java +++ b/sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.java @@ -33,7 +33,7 @@ import java.util.Map; @SqaleConstantRemediation("5min") public class VirtualLockUsageChecker extends SquidCheck { - private List keywords = Arrays.asList("add", "keyword2", "keyword3"); + private List keywords = Arrays.asList("add", "keyword2", "keyword3","password","name","type","token","username"); private Map> caches = new HashMap<>(); @Override diff --git a/sonar-keyware-plugins-cxx/src/main/java/org/sonar/cxx/squidbridge/AstScanner.java b/sonar-keyware-plugins-cxx/src/main/java/org/sonar/cxx/squidbridge/AstScanner.java index 4e840ec..d54a162 100644 --- a/sonar-keyware-plugins-cxx/src/main/java/org/sonar/cxx/squidbridge/AstScanner.java +++ b/sonar-keyware-plugins-cxx/src/main/java/org/sonar/cxx/squidbridge/AstScanner.java @@ -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; diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/BufferDataCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/BufferDataCheckerTest.java index 1ff71b3..b67320e 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/BufferDataCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/BufferDataCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyCheckerTest.java index 580049d..f5795a2 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/DLLVerifyCheckerTest.java @@ -29,6 +29,7 @@ public class DLLVerifyCheckerTest { CheckMessagesVerifier.verify(file.getCheckMessages()) .next().atLine(17).withMessage("在动态加载库前对输入数据进行验证") .next().atLine(43).withMessage("在动态加载库前对输入数据进行验证") + .next().atLine(83).withMessage("在动态加载库前对输入数据进行验证") .noMore(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmCheckerTest.java index e9a8fa2..693890c 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmCheckerTest.java @@ -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(); } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/FileAccessCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/FileAccessCheckerTest.java index a2ad779..b61a0ca 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/FileAccessCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/FileAccessCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyCheckerTest.java index 9185d5e..0238dfc 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyCheckerTest.java @@ -30,6 +30,7 @@ public class IntegerCountVerifyCheckerTest { CheckMessagesVerifier.verify(file.getCheckMessages()) .next().atLine(10).withMessage("來自用戶的整型数据进行算术运算应进行验证") .next().atLine(10).withMessage("來自用戶的整型数据进行算术运算应进行验证") + .next().atLine(18).withMessage("來自用戶的整型数据进行算术运算应进行验证") .noMore(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyCheckerTest.java index 9c1eb21..ebb9f84 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PRNGVerifyCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountCheckerTest.java index d6bdd13..6c4abf1 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PassWordCountCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyCheckerTest.java index ecd525c..ead3145 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/PathVerifyCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyCheckerTest.java index 75eacd1..f2b8e8b 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SQLVerifyCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SendMessageCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SendMessageCheckerTest.java index c056f17..17ead15 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SendMessageCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/SendMessageCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordCheckerTest.java index cdb5e7c..b9a18bf 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordCheckerTest.java @@ -29,6 +29,7 @@ public class UserInputPasswordCheckerTest { CheckMessagesVerifier.verify(file.getCheckMessages()) .next().atLine(18).withMessage("用户输入口令时对口令域进行掩饰,通常,用户输入的每一个字符都应该以“*”形式回显") .next().atLine(22).withMessage("用户输入口令时对口令域进行掩饰,通常,用户输入的每一个字符都应该以“*”形式回显") + .next().atLine(59).withMessage("用户输入口令时对口令域进行掩饰,通常,用户输入的每一个字符都应该以“*”形式回显") .noMore(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathCheckerTest.java index e012d4c..e25d73e 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VerificationPathCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageCheckerTest.java b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageCheckerTest.java index 22510db..6ee15a3 100644 --- a/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageCheckerTest.java +++ b/sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageCheckerTest.java @@ -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(); } } diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.cc index e3efafc..af9947a 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/BufferDataChecker.cc @@ -60,4 +60,16 @@ int main() { std::cout << std::endl; return 0; -} \ No newline at end of file +} + +void vulnerable_function(char *input) { + char buffer[10]; + strcpy(buffer, input); // 没有检查输入长度,可能导致缓冲区溢出 +} + +void example(){ + char value[11]; + printf("Enter The Value"); + scanf("%s",values);// 没有检查输入长度,可能导致缓冲区溢出 +} + diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.cc index 0997071..9957636 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/DLLVerifyChecker.cc @@ -75,4 +75,10 @@ int main() #endif return 0; +} + +void load(char * libaryName){ + char path[32] = "C:\\"; + strcat(path,libaryName); + HANDLE hlib = LoadLibrary(path); } \ No newline at end of file diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.cc index 9521a21..6abc2b7 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/EncryptionAlgorithmChecker.cc @@ -7,7 +7,7 @@ using namespace bcrypt; int main() { // 用户输入的原始密码 string password = "userPassword123"; - + AESEncryption aesEncryptor; // 使用cpp-bcrypt生成盐和哈希 // bcrypt::generate_salt(); // 生成一个随机盐 // string salt = bcrypt::get_salt(); diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.cc index 61a72ac..80d3fac 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FVNRPassWordChecker.cc @@ -1,5 +1,6 @@ #include // error #include // error +#include "aes.h"// error #include 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加密算法 } \ No newline at end of file diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.cc index 0d4dd4a..18c9507 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.cc @@ -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(); diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.cc index 7f19d4f..25b9b9a 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/IntegerCountVerifyChecker.cc @@ -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 -#include // MySQL Connector/C++库头文件 -#include - -// 假设你已经有了一个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 +#include +void sqlQuery(char * name){ + char sqlQuery[64] = "select * from cus where userid="; + strcat(sqlQuery,name); + strcat(sqlQuery,"'"); } \ No newline at end of file diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.cc index 85eaa07..13bb80a 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/SendMessageChecker.cc @@ -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); diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.cc index 77e29a7..fe4a397 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/UserInputPasswordChecker.cc @@ -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> userPath; - + strcat(path,filename); // 在获取用户输入之后立即对其进行验证 // checkPath(userPath); // verifyPath(userPath); diff --git a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.cc b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.cc index 6cb5daf..796f17f 100644 --- a/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.cc +++ b/sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/VirtualLockUsageChecker.cc @@ -11,6 +11,7 @@ int main() { string keyword3 = "北京市"; //error + char * password = ""; // 利用vector管理内存 // vector addressBuffer(add.begin(), add.end()); // diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java index d7f7691..a71d575 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/RulesList.java @@ -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> getHtmlRules() { diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java index aa2ef6e..97a4a78 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/HashSaltPassWordChecker.java @@ -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.*; diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java index c986d5b..0108225 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyChecker.java @@ -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; diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordInputTagJavaChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordInputTagJavaChecker.java index ced94c3..fffb8b1 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordInputTagJavaChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/PasswordInputTagJavaChecker.java @@ -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; /** * 用户输入口令时应对口令域进行掩饰。用户输入的每一个字符都应该以星号形式回显。 diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java index 4aa8039..2a4645e 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/RSAEncryptionChecker.java @@ -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; /** diff --git a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java index 391dbc2..eb876b8 100644 --- a/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java +++ b/sonar-keyware-plugins-java/src/main/java/com/keyware/sonar/java/rules/checkers/UpperCycleLimitRuleChecker.java @@ -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.*; diff --git a/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java index b5f3dd1..2591f7a 100644 --- a/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java +++ b/sonar-keyware-plugins-java/src/test/java/com/keyware/sonar/java/rules/checkers/OptionsVerifyCheckerTest.java @@ -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 *