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

1   using System;
2   using System.IO;
3   namespace TaintedGlobal
4   {
5     class TestTaintedGlobal
6     {
7       const string fileName = "File.dat";
8       public static int gVar = 0;
9   
10      public static void TaintedGlobalExample()
11      {
12              int t = getTaintedData();
13        gVar = t;         // CS.SV.TAINTED.GLOBAL
14      }
15  
16      public static int getTaintedData()
17      {
18        try
19        {
20          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
21          {
22            return(br.ReadInt32());
23          }
24        }
25        catch (Exception e)
26        {
27          Console.WriteLine(e);
28        }
29      }
30    }
31  }

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

1   using System;
2   using System.IO;
3   namespace TaintedGlobal
4   {
5     class TestTaintedGlobal
6     {
7       const string fileName = "File.dat";
8       const int maxBuf = 10;
9       public static int gVar = 0;
10  
11      public static void TaintedGlobalExample()
12      {
13              int t = getTaintedData();
14        if(t < maxBuf)
15        {
16          gVar = t;
17        }
18      }
19  
20      public static int getTaintedData()
21      {
22        try
23        {
24          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
25          {
26            return(br.ReadInt32());
27          }
28        }
29        catch (Exception e)
30        {
31          Console.WriteLine(e);
32        }
33      }
34    }
35  }

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

1   using System;
2   using System.IO;
3   namespace TaintedGlobal
4   {
5     class TestTaintedGlobal
6     {
7       const string fileName = "File.dat";
8   
9       public static void TaintedGlobalExample()
10      {
11              int t = getTaintedData();
12        TaintedTrueGlobal.gVar1 = t;  // CS.SV.TAINTED.GLOBAL
13      }
14  
15      public static int getTaintedData()
16      {
17        try
18        {
19          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
20          {
21            return(br.ReadInt32());
22          }
23        }
24        catch (Exception e)
25        {
26          Console.WriteLine(e);
27        }
28      }
29    }
30  
31    static class TaintedTrueGlobal
32    {
33      public static int gVar1= 0;
34    }
35  }

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

1   using System;
2   using System.IO;
3   
4   namespace TaintedGlobal
5   {
6     class TestTaintedGlobal
7     {
8       const string fileName = "File.dat";
9       const int maxBuf = 10;
10  
11      public static void TaintedGlobalExample()
12      {
13              int t = getTaintedData();
14        if(t < maxBuf)
15        {
16          TaintedTrueGlobal.gVar1 = t;  
17        }
18      }
19  
20      public static int getTaintedData()
21      {
22        try
23        {
24          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
25          {
26            return(br.ReadInt32());
27          }
28        }
29        catch (Exception e)
30        {
31          Console.WriteLine(e);
32        }
33      }
34    }
35  
36     static class TaintedTrueGlobal
37    {
38      public static int gVar1= 0;
39    }
40  }

Klocwork no longer reports a defect, since the integer value 'temp' is validated at line 16 before being used to initialize the global variable.