CS.SV.TAINTED.GLOBAL

Use of Unvalidated Integer in an Assignment Operation

This checker reports a defect whenever tainted data is used to assign a globally visible data field.

Vulnerability and risk

Global variables, such as C# public static class fields, are visible in the entire program scope. It can be difficult for a programmer or an analysis tool to fully control their assignments or reads in the program. The possibility of a reduced understanding of the global variable effect on the program control flow can introduce a security risk when integer data input to the code is not validated properly and is used to assign a global variable.

Vulnerable code example 1

Copy
   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);
        }
      }
    }
  }

In the above example, an attacker can provide the large value for global variable ‘gVar’. If the assignment operation at line 13 overflows, this can result in a negative value of variable ‘gVar’, and cause unexpected program behaviour.

Klocwork reports a CS.SV.TAINTED.GLOBAL defect at line 13, indicating: “Unvalidated integer value ’t’ that is received from ’getTaintedData’ at line 12 is used to initialize a field at line 13.”

Fixed code example 1

Copy
   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 no longer reports a defect, since the integer value 't' is validated at line 14 before being used to initialize the global variable at line 16.

Vulnerable code example 2

Copy
   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;
    }
  }

In the above example, an attacker can provide the large value for global variable ‘gVar1’. If the assignment operation at line 12 overflows, this can result in a negative value of variable ‘gVar1’, and cause unexpected program behavior.

Klocwork reports a CS.SV.TAINTED.GLOBAL defect at line 12, indicating: “Unvalidated integer value’t’ that is received from ’getTaintedData’ at line 11 is used to initialise a field at line 12.”

Fixed code example 2

Copy
   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 no longer reports a defect, since the integer value 'temp' is validated at line 16 before being used to initialize the global variable.