parent
aaee78b3fd
commit
c0365cb297
@ -0,0 +1,17 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||||
|
* 项目名称:信息安全性设计准则检查插件 |
||||||
|
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
||||||
|
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||||
|
*/ |
||||||
|
package com.keyware.sonar.cxx.rules; |
||||||
|
|
||||||
|
/** |
||||||
|
* C++ 安全设计准则检查规则属性 |
||||||
|
* |
||||||
|
* @author GuoXin |
||||||
|
* @date 2024/1/18 |
||||||
|
*/ |
||||||
|
public class SecurityDesignRuleProperties { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||||
|
* 项目名称:信息安全性设计准则检查插件 |
||||||
|
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
||||||
|
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.keyware.sonar.cxx.rules.checkers; |
||||||
|
|
||||||
|
import com.sonar.cxx.sslr.api.AstNode; |
||||||
|
import com.sonar.cxx.sslr.api.Grammar; |
||||||
|
import org.sonar.api.utils.log.Logger; |
||||||
|
import org.sonar.api.utils.log.Loggers; |
||||||
|
import org.sonar.check.Priority; |
||||||
|
import org.sonar.check.Rule; |
||||||
|
import org.sonar.cxx.parser.CxxGrammarImpl; |
||||||
|
import org.sonar.cxx.squidbridge.api.CheckMessage; |
||||||
|
import org.sonar.cxx.squidbridge.api.SourceCode; |
||||||
|
import org.sonar.cxx.visitors.MultiLocatitionSquidCheck; |
||||||
|
|
||||||
|
import javax.annotation.Nonnull; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 应通过用户名口令、数字证书等其他手段对主机身份进行鉴别 |
||||||
|
* <p>仅检测代码中有没有用户名口令和数字证书</p> |
||||||
|
* |
||||||
|
* @author GuoXin |
||||||
|
* @date 2024/1/24 |
||||||
|
*/ |
||||||
|
@Rule(key = "HostIdentityVerifyChecker", name = "程序中未识别到通过用户名口令或者数字证书验证等安全认证逻辑", description = "应通过用户名口令、数字证书等其他手段对主机身份进行鉴别", priority = Priority.MAJOR, tags = {"28suo"}) |
||||||
|
public class HostIdentityVerifyChecker extends MultiLocatitionSquidCheck<Grammar> { |
||||||
|
private static final Logger LOG = Loggers.get(HostIdentityVerifyChecker.class); |
||||||
|
private SourceCode project; |
||||||
|
|
||||||
|
private boolean hasUsername = false; |
||||||
|
private boolean hasPassword = false; |
||||||
|
private boolean hasCertificate = false; |
||||||
|
|
||||||
|
private final Set<String> SSL_FUNCTIONS = Set.of( |
||||||
|
"SSL_use_certificate_file", |
||||||
|
"SSL_use_PrivateKey_file", |
||||||
|
"SSL_use_RSAPrivateKey_file", |
||||||
|
"SSL_CTX_use_certificate_file", |
||||||
|
"SSL_CTX_use_RSAPrivateKey_file", |
||||||
|
"SSL_CTX_use_PrivateKey_file", |
||||||
|
"SSL_CTX_use_certificate_chain_file", |
||||||
|
"SSL_use_certificate_chain_file", |
||||||
|
"SSL_library_init", |
||||||
|
"PEM_read_X509", |
||||||
|
"d2i_X509_bio", |
||||||
|
"X509_verify", |
||||||
|
"X509_check_issued", |
||||||
|
"X509_get_notBefore", |
||||||
|
"X509_get_notAfter", |
||||||
|
"X509_get_subject_name", |
||||||
|
"X509_get_issuer_name", |
||||||
|
"X509_get_pubkey", |
||||||
|
"X509_STORE_CTX_init", |
||||||
|
"X509_STORE_add_cert", |
||||||
|
"X509_verify_cert" |
||||||
|
); |
||||||
|
|
||||||
|
@Override |
||||||
|
public void init() { |
||||||
|
LOG.info("[KeyWare][C++检查] >> 应通过用户名口令、数字证书等其他手段对主机身份进行鉴别"); |
||||||
|
if (project == null) { |
||||||
|
project = getContext().peekSourceCode(); |
||||||
|
} |
||||||
|
subscribeTo(CxxGrammarImpl.functionDefinition, CxxGrammarImpl.simpleDeclaration, CxxGrammarImpl.postfixExpression); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void visitNode(@Nonnull AstNode astNode) { |
||||||
|
if ((hasUsername && hasPassword) || hasCertificate) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (astNode.is(CxxGrammarImpl.functionDefinition)) { |
||||||
|
visitFunctionDefinition(astNode); |
||||||
|
} else if (astNode.is(CxxGrammarImpl.simpleDeclaration)) { |
||||||
|
visitSimpleDeclaration(astNode); |
||||||
|
} else if (astNode.is(CxxGrammarImpl.postfixExpression)) { |
||||||
|
visitPostfixExpression(astNode); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void visitFunctionDefinition(@Nonnull AstNode astNode) { |
||||||
|
astNode.getDescendants(CxxGrammarImpl.parameterDeclaration).forEach(this::checkDeclarationNode); |
||||||
|
} |
||||||
|
|
||||||
|
private void visitSimpleDeclaration(@Nonnull AstNode astNode) { |
||||||
|
astNode.getDescendants(CxxGrammarImpl.declarator).forEach(this::checkDeclarationNode); |
||||||
|
} |
||||||
|
|
||||||
|
private void visitPostfixExpression(@Nonnull AstNode astNode) { |
||||||
|
var nameNode = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId); |
||||||
|
if (nameNode == null) { |
||||||
|
nameNode = astNode.getFirstDescendant(CxxGrammarImpl.className); |
||||||
|
} |
||||||
|
if (nameNode != null) { |
||||||
|
var nameStr = nameNode.getTokenValue(); |
||||||
|
if (SSL_FUNCTIONS.contains(nameStr)) { |
||||||
|
hasCertificate = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void checkDeclarationNode(@Nonnull AstNode astNode) { |
||||||
|
var paramNode = astNode.getFirstDescendant(CxxGrammarImpl.declaratorId); |
||||||
|
if (paramNode != null) { |
||||||
|
var paramName = paramNode.getTokenValue(); |
||||||
|
paramName = paramName.toLowerCase().replace("-", "").replace("_", ""); |
||||||
|
if ("username".equals(paramName)) { |
||||||
|
hasUsername = true; |
||||||
|
} else if ("password".equals(paramName)) { |
||||||
|
hasPassword = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 当访问器销毁时执行,代表所有文件已经被访问完毕,可以进行最后的处理。 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void destroy() { |
||||||
|
if (!(hasPassword && hasUsername) && !hasCertificate) { |
||||||
|
project.log(new CheckMessage(this, "应通过用户名口令、数字证书等其他手段对主机身份进行鉴别")); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||||
|
* 项目名称:信息安全性设计准则检查插件 |
||||||
|
* 项目描述:用于检查源代码的安全性设计准则的Sonarqube插件 |
||||||
|
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.keyware.sonar.cxx.rules.checkers; |
||||||
|
|
||||||
|
import com.keyware.sonar.cxx.CxxFileTesterHelper; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.sonar.api.batch.fs.InputFile; |
||||||
|
import org.sonar.cxx.CxxAstScanner; |
||||||
|
import org.sonar.cxx.config.CxxSquidConfiguration; |
||||||
|
import org.sonar.cxx.squidbridge.api.SourceCode; |
||||||
|
import org.sonar.cxx.squidbridge.api.SourceProject; |
||||||
|
import org.sonar.cxx.squidbridge.indexer.QueryByType; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
|
||||||
|
/** |
||||||
|
* 测试规则:应通过用户名口令、数字证书等其他手段对主机身份进行鉴别 |
||||||
|
* |
||||||
|
* @author GuoXin |
||||||
|
* @date 2024/1/24 |
||||||
|
*/ |
||||||
|
public class HostIdentityVerifyCheckerTest { |
||||||
|
@Test |
||||||
|
public void checkTest() throws IOException { |
||||||
|
var checker = new HostIdentityVerifyChecker(); |
||||||
|
var tester = CxxFileTesterHelper.create("HostIdentityVerifyChecker.cc"); |
||||||
|
var scanner = CxxAstScanner.create(new CxxSquidConfiguration(), checker); |
||||||
|
Set<InputFile> inputFiles = Set.of(tester.asInputFile()); |
||||||
|
scanner.scanInputFiles(inputFiles); |
||||||
|
Collection<SourceCode> squidSourceFiles = scanner.getIndex().search(new QueryByType(SourceProject.class)); |
||||||
|
assertThat(squidSourceFiles).size().isEqualTo(1); |
||||||
|
squidSourceFiles.forEach(sourceCode -> { |
||||||
|
assertThat(sourceCode.getCheckMessages()).size().isEqualTo(1); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
#include <iostream> |
||||||
|
#include <string> |
||||||
|
#include <boost/asio.hpp> |
||||||
|
// 本示例中对合规代码进行了注释
|
||||||
|
|
||||||
|
// 假设有一个函数去异步验证用户名和密码
|
||||||
|
/*void verify_credentials(const std::string& username, const std::string& password) {
|
||||||
|
// 如果验证成功,则执行相应操作
|
||||||
|
if (is_valid(username, password)) { |
||||||
|
std::cout << "Authentication successful." << std::endl; |
||||||
|
} else { |
||||||
|
std::cout << "Invalid credentials." << std::endl; |
||||||
|
} |
||||||
|
}*/ |
||||||
|
|
||||||
|
int main() { |
||||||
|
/*std::string user_name, pass_word;
|
||||||
|
std::cout << "Enter your username: "; |
||||||
|
std::cin >> user_name; |
||||||
|
std::cout << "Enter your password: "; |
||||||
|
std::getline(std::cin, pass_word); |
||||||
|
|
||||||
|
// 调用验证函数
|
||||||
|
verify_credentials(user_name, pass_word);*/ |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
#include <openssl/x509.h> |
||||||
|
#include <openssl/pem.h> |
||||||
|
#include <openssl/ssl.h> |
||||||
|
#include <openssl/err.h> |
||||||
|
|
||||||
|
bool verifyCertificate(const std::string& certPath) { |
||||||
|
// 初始化OpenSSL库
|
||||||
|
/*SSL_library_init();
|
||||||
|
OpenSSL_add_all_algorithms(); |
||||||
|
ERR_load_crypto_strings(); |
||||||
|
|
||||||
|
// 加载证书文件
|
||||||
|
FILE* certFile = fopen(certPath.c_str(), "r"); |
||||||
|
if (!certFile) { |
||||||
|
perror("Failed to open certificate file"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
X509* x509Cert = PEM_read_X509(certFile, NULL, NULL, NULL); |
||||||
|
fclose(certFile); |
||||||
|
|
||||||
|
if (!x509Cert) { |
||||||
|
ERR_print_errors_fp(stderr); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// 这里只做简单的证书有效性检查,真实场景下需要构建完整的信任链并验证到根CA
|
||||||
|
int result = X509_verify(x509Cert, NULL); |
||||||
|
|
||||||
|
|
||||||
|
// 释放资源
|
||||||
|
X509_free(x509Cert); |
||||||
|
|
||||||
|
// 返回验证结果
|
||||||
|
return (result == 1);*/ |
||||||
|
} |
||||||
|
|
||||||
|
int main2() { |
||||||
|
const std::string certPath = "/path/to/certificate.pem"; |
||||||
|
bool isVerified = verifyCertificate(certPath); |
||||||
|
if (isVerified) { |
||||||
|
std::cout << "The certificate has been verified successfully." << std::endl; |
||||||
|
} else { |
||||||
|
std::cout << "Failed to verify the certificate." << std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
// 清理OpenSSL库
|
||||||
|
EVP_cleanup(); |
||||||
|
ERR_free_strings(); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
Loading…
Reference in new issue