优化准则:在程序中指定允许访问的文件或目录,在访问文件或目录前对路径名进行验证,确保仅允许访问指定的文件或目录

wuhaoyang
wuhaoyang 10 months ago
parent 28d4ce998d
commit 064bb0309e
  1. 52
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.java
  2. 2
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/FileAccessCheckerTest.java
  3. 6
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/FileAccessChecker.cc

@ -28,6 +28,7 @@ import org.sonar.cxx.squidbridge.checks.SquidCheck;
@SqaleConstantRemediation("5min") @SqaleConstantRemediation("5min")
public class FileAccessChecker extends SquidCheck<Grammar> { public class FileAccessChecker extends SquidCheck<Grammar> {
private boolean filePathChecked = false; private boolean filePathChecked = false;
private boolean filePathUsedInIf = false;
@Override @Override
public void init() { public void init() {
@ -47,56 +48,47 @@ public class FileAccessChecker extends SquidCheck<Grammar> {
private void checkIfStatement(AstNode ifStatement) { private void checkIfStatement(AstNode ifStatement) {
AstNode condition = ifStatement.getFirstChild(CxxGrammarImpl.condition); AstNode condition = ifStatement.getFirstChild(CxxGrammarImpl.condition);
filePathUsedInIf = containsFilePathCheck(condition);
if (containsFilePathCheck(condition)) { if (!filePathUsedInIf) {
filePathChecked = true; createViolation(ifStatement, "在访问文件或目录前需要对路径名进行验证");
} }
filePathUsedInIf = false;
} }
private void checkDeclaration(AstNode declaration) { private void checkDeclaration(AstNode declaration) {
AstNode declaratorNode = declaration.getFirstDescendant(CxxGrammarImpl.declarator); AstNode declaratorNode = declaration.getFirstDescendant(CxxGrammarImpl.declarator);
filePathChecked = containsFilePathCheck(declaratorNode);
if (declaratorNode != null) { if (declaratorNode != null && !filePathChecked) {
String variableName = declaratorNode.getTokenOriginalValue(); String variableName = declaratorNode.getTokenOriginalValue();
if (variableName != null && variableName.equals("filePath")) {
if ("filePath".equals(variableName)) { System.out.println(variableName);
if (!filePathChecked) { getContext().createLineViolation(this, "在访问文件或目录前需要对路径名进行验证", declaratorNode);
System.out.println("在访问文件或目录前需要对路径名进行验证:"+variableName);
getContext().createLineViolation(this, "在访问文件或目录前需要对路径名进行验证", declaratorNode);
}
} }
} }
} }
private void checkStatement(AstNode statement) { private void checkStatement(AstNode statement) {
AstNode condition = statement.getFirstChild(CxxGrammarImpl.condition); AstNode condition = statement.getFirstChild(CxxGrammarImpl.condition);
filePathChecked = containsFilePathCheck(condition);
if (containsFilePathCheck(condition)) {
filePathChecked = true;
}
}
private boolean containsFilePathCheck(AstNode condition) {
return recursiveCheck(condition);
} }
private boolean recursiveCheck(AstNode node) { private boolean containsFilePathCheck(AstNode node) {
if (node == null) { if (node != null && node.getTokenOriginalValue().equals("filePath")) {
return false; return true;
} }
if (node.is(CxxGrammarImpl.identifierList)) { if (node != null) {
// 如果是标识符,检查是否是 filePath
String identifierName = node.getTokenOriginalValue();
return "filePath".equals(identifierName);
} else {
// 递归检查子节点
for (AstNode child : node.getChildren()) { for (AstNode child : node.getChildren()) {
if (recursiveCheck(child)) { // 如果 if 中使用了 filePath,则停止递归并跳过 ifstream file(filePath) 检查
if (containsFilePathCheck(child)) {
return true; return true;
} }
} }
return false;
} }
return false; // 节点或其任何子节点中找不到“filePath”
}
private void createViolation(AstNode node, String message) {
getContext().createLineViolation(this, message, node);
} }
} }

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

@ -5,10 +5,12 @@
using namespace std; using namespace std;
int main() { int main() {
string filePath = "C:\\Users\\user\\Desktop\\test.txt";//error
string filePath = "C:\\Users\\user\\Desktop\\test.txt";
if (filePath) { int a = 5;
if (a<5) {
ifstream file(filePath); ifstream file(filePath);
cout << "File opened successfully." << endl; cout << "File opened successfully." << endl;

Loading…
Cancel
Save