CS.SV.TAINTED.GLOBAL

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

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

漏洞与风险

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

漏洞代码示例 1

复制
   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();
        gVar = t;         // CS.SV.TAINTED.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);
        }
      }
    }
  }

在以上示例中,攻击者可以为全局变量 gVar 提供大的值。如果第 13 行中的分配运算溢出,可能导致变量 gVar 的值为负值,从而出现意外的程序行为。

Klocwork 报告第 13 行出现 CS.SV.TAINTED.GLOBAL 缺陷,指出:“从第 12 行 getTaintedData 接收到的未验证整数值 t 被用来初始化第 13 行中的字段”。

修正代码示例 1

复制
   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)
        {
          gVar = 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);
        }
      }
    }
  }

Klocwork 不再报告缺陷,因为整数值 t 在用于初始化第 16 行的全局变量前已在第 14 行经过验证。

漏洞代码示例 2

复制
   using System;
   using System.IO;
   namespace TaintedGlobal
   {
     class TestTaintedGlobal
     {
       const string fileName = "File.dat";
   
       public static void TaintedGlobalExample()
      {
              int t = getTaintedData();
        TaintedTrueGlobal.gVar1 = t;  // CS.SV.TAINTED.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);
        }
      }
    }
  
    static class TaintedTrueGlobal
    {
      public static int gVar1= 0;
    }
  }

在以上示例中,攻击者可以为全局变量 gVar1 提供大的值。如果第 12 行中的分配运算溢出,可能导致变量 gVar1 的值为负值,从而出现意外的程序行为。

Klocwork 报告第 12 行出现 CS.SV.TAINTED.GLOBAL 缺陷,指出:“从第 11 行 getTaintedData 而接收到的未验证整数值 t 被用来初始化第 12 行中的字段”。

修正代码示例 2

复制
   using System;
   using System.IO;
   
   namespace TaintedGlobal
   {
     class TestTaintedGlobal
     {
       const string fileName = "File.dat";
       const int maxBuf = 10;
  
      public static void TaintedGlobalExample()
      {
              int t = getTaintedData();
        if(t < maxBuf)
        {
          TaintedTrueGlobal.gVar1 = 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);
        }
      }
    }
  
     static class TaintedTrueGlobal
    {
      public static int gVar1= 0;
    }
  }

Klocwork 不再报告缺陷,因为整数值 temp 在用于初始化全局变量前已在第 16 行经过验证。