SV.TAINTED.INJECTION

下游注入中的未经验证的输入

每当从用户或外部环境接受输入的时候,都应该在使用前验证类型、长度、格式和范围。在得到妥善验证之前,数据将被视为已被污染。SV.TAINTED 系列检查器会查找代码中使用已污染数据的情况。

注入问题包括了一系列通过将控制平面数据注入到用户控制的数据平面而标记的问题。SQL 注入是注入情况的一个典型示例。SV.TAINTED.INJECTION 检查器会标记出将未经验证的数据作为参数传递给执行命令的函数的情况,比如 SQL 语句、进程创建命令以及文件操纵函数。

漏洞与风险

当代码输入未经妥善验证时,攻击者可以精心地将输入编制为并非应用程序所预期的格式。接收意外的输入可能导致控制流被改变、任意的资源控制以及任意的代码执行。通过此类机会,攻击者可以

  • 提供无法预料的值并导致程序崩溃
  • 导致过度的资源消耗
  • 读取机密数据
  • 使用恶意输入来修改数据或改变控制流
  • 执行任意命令

注入攻击通常涉及到敏感数据以及可以实现进一步漏洞利用的数据的泄露。此类攻击通常会更改进程流,并经常包括任意代码执行。

缓解与预防

要避免受污染输入错误:

  • 了解所有可能导致不受信任的输入进入软件的区域:参数或自变量、Cookie、读取自网络的输入、环境变量、反向 DNS 查找、查询结果、文件名、数据库以及任何外部系统
  • 使用白名单或“已知正确”策略进行输入,而不是仅依赖于黑名单或“已知错误”策略
  • 确保对输入的所有相关属性进行验证,包括长度、输入类型、范围、缺失或额外输入、语法以及一致性
  • 如果在应用程序的客户端一侧有安全性检查,请确保也在服务器端重复一遍
  • 如果应用程序组合来自多个来源的输入,请在组合来源之后再执行验证

漏洞代码示例

复制
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  
  int main() {
    char buf[1024];
    char *s;
    char command[2048];
  
   printf("Enter Name to look:\n");
   fgets(buf, 1023, stdin);
   buf[1023] = '\0';
   s = strchr(buf,'\n');
   if (s != NULL) {
     *s = '\0';
   }
   strcpy(command, "grep \"");
   strcat(command, buf);
   strcat(command, "\" phone_book");
   system(command);
   return 0;
 }

Klocwork 针对第 20 行生成问题报告,表明通过调用 fgets 获得的未经验证的字符串 command 可通过调用 system 而作为命令行运行。在这种情况下,SV.TAINTED.INJECTION 检查器标记出传递给执行命令的函数的可能被污染的数据,这些数据可能被恶意用户利用。Klocwork 警告使您可以确认向系统函数传递的是未受污染的数据。