CWE-14: Compiler Removal of Code to Clear Buffers(编译器对清除缓冲区语句的删除)
ID: 14 类型:变量 | 状态:草稿 |
描述
源代码中存在清除存储有敏感数据内存块的语句,但是,编译器优化操作使这些语句失效,这也称为“死区删除”。
扩展描述
在以下时点会出现这样的编译器优化错误:
- 1. 机密数据存储在内存中
- 2. 机密数据通过覆盖其内容从内存中清除
- 3. 源代码是使用优化编译器编译的,该编译器标识并删除覆盖死存储内容的函数,因为随后不会使用这块内存。
关联视图
与“研究层面”视图(CWE-1000)相关
与“开发层面”视图(CWE-699)相关
引入模式
阶段 | 说明 |
实现 | |
编译及链接 |
应用平台
语言
C (出现的可能性不确定)
C++ (出现的可能性不确定)
后果
范围 | 冲击 | 可能性 |
保密性 | 技术冲击: 内存读取; 越过保护机制 此弱点将允许读取尚未从内存中清除的数据。如果此数据包含敏感密码信息,攻击者就能够读取密码并使用这些信息越过保护机制. |
示例
例1
以下代码从用户处读取密码,使用密码连接到后端主机,然后尝试使用memset()从内存中清除密码。
(问题代码)
Example Language: C
void GetData(char *MFAddr) {
char pwd[64];
if (GetPasswordFromUser(pwd, sizeof(pwd))) {
if (ConnectToMainframe(MFAddr, pwd)) {
// Interaction with mainframe
}
}
memset(pwd, 0, sizeof(pwd));
}
示例中的代码如果全部执行,将正确运行,但是如果代码使用优化编译器编译,例如微软Visual C++.NET或GCC 3 .x,那么memset()的调用将会因为“死存储”被删除,因为缓冲区PWD在其值被重写后未被使用[18 ]。由于缓冲区pwd包含敏感值,因此如果数据保留在内存中,应用程序可能容易受到攻击。如果攻击者能够访问正确的内存区域,他们可以使用恢复的密码来控制系统。
为了防止攻击者掌握系统中的秘密信息,通常会覆盖在内存中操作的敏感数据,如密码或加密密钥。然而,随着优化编译器的出现,程序并不总是按照源代码的方式运行。在本例中,编译器将对memset()的调用解释为死代码,因为随后不会使用正在写入的内存,尽管存在安全方面的动机使这些操作发生。这里的问题是,许多编译器,而且事实上许多编程语言,在努力提高效率时没有考虑到这一点和其他安全问题。
攻击者通常通过使用核心转储或运行机制访问特定应用程序使用的内存并恢复机密信息来利用这类漏洞。一旦攻击者能够访问机密信息,就可以相对直接地进一步利用系统,并可能损害应用程序与之交互的其他资源。
应对措施
阶段: 实现. 如果可以的话,将敏感数据存储到"volatile"内存中。 |
阶段: 编译及链接 如果可能,请配置编译器,使其不会删除死区。 |
阶段: 架构与设计 在可能的情况下,对软件系统使用的敏感数据进行加密。 |
种属
关系 | 类型 | ID | 名称 |
属于 | | 2 | |
属于 | | 729 | |
属于 | | 747 | CERT C Secure Coding Standard (2008) Chapter 14 - Miscellaneous (MSC) |
属于 | | 883 | |
属于 | | 884 | |
属于 | | 963 |