CS.SV.TAINTED.CALL.GLOBAL

在赋值运算中使用未经验证的 整数

但凡使用已污染的数据通过函数调用来分配全局可见的数据字段时,此检查器都会报告缺陷。

漏洞与风险

全局变量(例如 C# 公共静态类字段)在整个程序范围内都可见。程序员或分析工具可能难以完全控制其在程序中的分配或读取。降低全局变量对程序控制流的影响的了解,可能会在代码的整数数据输入未经适当验证并用于分配全局变量时引入安全风险。

漏洞代码示例

复制
   using System;
   using System.IO;
   namespace TaintedGlobal
   {
     class TestTaintedGlobal
     {
       const string fileName = "File.dat";
       public static int gVar = 0;
   
      public static void TaintedGlobalExample()
      {
              int t = getTaintedData();
        bar(t); // CS.SV.TAINTED.CALL.GLOBAL
      }
  
      public static int getTaintedData()
      {
        try
        {
          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
          {
            return(br.ReadInt32());
          }
        }
        catch (Exception e)
        {
          Console.WriteLine(e);
        }
      }

      public static void bar(int value)
      {
        gVar = value;
      }
    }
  }

在以上示例中,攻击者可能会为全局变量 gVar 提供任意值,该变量随后可能会用于代码中程序员无法控制甚至未意识到的其他位置。这样就可能会引入涉及该变量的安全漏洞风险。

Klocwork 报告第 12 行出现 SV.TAINTED.CALL.GLOBAL 缺陷,这表示“从第 12 行 getTaintedData 而接收到的未验证整数值 t 被用来通过第 13 行的调用 bar() 分配全局变量”。

修正代码示例

复制
   using System;
   using System.IO;
   
   namespace TaintedGlobal
   {
     class TestTaintedGlobal
     {
       const string fileName = "File.dat";
       const int maxBuf = 10;
      public static int gVar = 0;
  
      public static void TaintedGlobalExample()
      {
              int t = getTaintedData();
        if(t < maxBuf)
        {
          bar(t); 
        }
      }
  
      public static int getTaintedData()
      {
        try
        {
          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
          {
            return(br.ReadInt32());
          }
        }
        catch (Exception e)
        {
          Console.WriteLine(e);
        }
      }
  
      public static void bar(int value)
      {
        gVar = value;
      }
    }
  }

由于整型值 t 已经过验证,因此 Klocwork 不再报告缺陷。