ABV.TAINTED

缓冲区溢出 — 受污染的输入中的数组索引超出边界

ABV.TAINTED 可检查由未验证或受污染的输入数据(源自用户或外部设备)引起的缓冲区溢出。此检查器会通过代码标记执行路径,在该代码中,缓冲区溢出中涉及的输入数据未进行验证。

漏洞与风险

缓冲区溢出通常是应用程序攻击和利用的来源。

缓解与预防

要避免发生受污染的输入引起的这些攻击

  • 确保在可能发生溢出的行之前插入验证条件
  • 考虑到相应输入的所有可能相关的输入属性,包括长度、输入类型、可接受值的完整范围、缺少或多余的输入、语法、相关字段的一致性,以及业务规则遵从性
  • 确保已确认范围的最小值和最大值,以避免错误接受负值

漏洞代码示例

复制
  #include <stdio.h>
  void wrapped_read(char* buf, int count) {
     fgets(buf, count, stdin);
  }
  
  void TaintedAccess()
  {
     char buf1[12];
     char buf2[12];
 
    char dst[16];
 
    wrapped_read(buf1, sizeof(buf1));
    wrapped_read(buf2, sizeof(buf2));
    sprintf(dst, "%s-%s\n", buf1, buf2);
 }

Klocwork 针对第 15 行生成缓冲区溢出报告,指出未验证的输入用作 dst 的数组索引。数组 dst 的大小定义为 16,但是第 13 和 14 行可能生成 22 个字符的输入,并以 null 终止。在本例中,输入数据尚未针对缓冲区大小进行检查,因此将其视为已受污染。

修正代码示例

复制
  #include <stdio.h>
  void wrapped_read(char* buf, int count) {
     fgets(buf, count, stdin);
  }
  
  void TaintedAccess()
  {
     char buf1[12];
     char buf2[12];
 
    char dst[25];
 
    wrapped_read(buf1, sizeof(buf1));
    wrapped_read(buf2, sizeof(buf2));
    sprintf(dst, "%s-%s\n", buf1, buf2);
 }

                                                

在该修正代码示例中,dst 的大小已正确定义为 25。

扩展

此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 C/C++ 分析。