C++ 应用程序安全:十大漏洞及防护方法

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++ 应用程序安全:十大漏洞及防护方法



C++ 是一种强大的系统编程语言,但其灵活性和直接内存访问能力使应用程序容易受到严重攻击。根据 OWASP 和 CWE,工业软件(从游戏到航空电子设备)中的许多关键漏洞正是由 C++ 代码错误引起的。在本文中,我们将分析十大最危险的漏洞,提供代码示例,并展示如何避免它们。



1. 缓冲区溢出

一种经典漏洞,允许攻击者覆盖相邻的内存区域。它发生在未检查大小的情况下复制数据时。



// Vulnerable code#include <cstring>void vulnerable(char* input) {    char buffer[10];    strcpy(buffer, input); // Danger: if input is longer than 9 characters}// Secure versionvoid secure(char* input, size_t len) {    char buffer[10];    if (len < sizeof(buffer)) {        strncpy(buffer, input, sizeof(buffer) - 1);        buffer[sizeof(buffer) - 1] = '\\0';    }}


防护方法:使用 std::string、std::vector 或长度限制函数(strncpy、snprintf)。启用编译器标志 -fstack-protector-strong 和 -D_FORTIFY_SOURCE=2。



2. 释放后使用

访问已经释放的内存。导致在另一个区域读写或执行任意代码。



// Vulnerable codeint* ptr = new int(42);delete ptr;*ptr = 100; // Error! ptr is no longer valid// Secure versionint* ptr = new int(42);delete ptr;ptr = nullptr; // Nullify the pointerif (ptr) *ptr = 100; // Check before use


防护方法:使用智能指针(std::unique_ptr、std::shared_ptr),在 delete 后将原始指针置空,应用清理工具(-fsanitize=address)。



3. 整数溢出

算术运算期间超出允许范围。常用于绕过缓冲区大小检查。



// Vulnerable codesize_t size = 0;size_t user_input = 4294967295; // 2^32 - 1size_t total = size + user_input + 1; // Overflow!// Secure version with checkif (user_input > SIZE_MAX - size) {    throw std::overflow_error("Size too large");}size_t total = size + user_input + 1;


防护方法:使用固定宽度类型(uint32_t),在操作前检查溢出,使用 __builtin_add_overflow(GCC/Clang)。



4. 空指针解引用

尝试访问 NULL 地址处的内存。导致程序崩溃(段错误)或 DoS 漏洞。



// Vulnerable codevoid process(int* ptr) {    *ptr = 10; // If ptr == nullptr — crash}// Secure versionvoid process(int* ptr) {    if (!ptr) {        throw std::invalid_argument("Null pointer received");    }    *ptr = 10;}


防护方法:使用前始终检查指针是否为 nullptr,返回 std::optional 而不是原始指针。



5. 内存泄漏

丢失对已分配内存的访问而不释放。随着时间的推移,会耗尽系统资源。



// Vulnerable codevoid leak() {    int* data = new int[100];    // Forgot delete[] data — leak}// Secure versionvoid no_leak() {    std::unique_ptr<int[]> data = std::make_unique<int[]>(100);    // Memory will be freed automatically}


防护方法:使用 RAII(智能指针、容器)

博客

书籍推荐