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

整数値「t」は、16 行目でグローバル変数の初期化に使用される前に 14 行目で検証されるため、Klocwork は欠陥を報告しなくなります。

脆弱コード例 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;
    }
  }

整数値「temp」は、グローバル変数の初期化に使用される前に 16 行目で検証されるため、Klocwork は欠陥を報告しなくなります。