CS.SV.TAINTED.LOOP_BOUND.RESOURCE

汚染されたデータによって終了条件が制御されるループ内でのリソース割り当て

入力がユーザーまたは外部環境から受け入れられるときは常に、入力のタイプ、長さ、書式、および範囲を検証してから使用する必要があります。適切に検証されるまでは、そのデータは汚染していると言われます。CS.SV.TAINTED ファミリーのチェッカーは、コードでの汚染データの使用箇所を探します。

この CS.SV.TAINTED.LOOP_BOUND.RESOURCE チェッカーは、ループ内でマネージドまたはアンマネージドのリソースが割り当てられている間、未検証の引数がループ境界として使用されるコードにフラグを立てます。

ループ本体の最後でリソースへの参照が残っていない場合、一部のリソースはガベージコレクターによってすぐに破棄される可能性がありますが、そのような破棄のタイミングは保証されません。さらに、割り当てられたリソースのなかには存続期間が長くなるものがあり、その結果、リソースが過剰に消費され、リソースを使い果たすかプログラムが失敗する可能性があります。この動作は、このようなループからの終了条件が外部入力によって制御されるときに、潜在的な攻撃者によって悪用される可能性があります。

脆弱性とリスク

コードへの入力が適切に検証されないと、攻撃者は入力をアプリケーションが予期しない形で作成することができます。意図しない入力を受け取ると、制御フローの改変、任意リソースの制御、および任意のコードの実行につながる可能性があります。この種のチャンスがある場合、攻撃者は次のことを行えます。

  • 予期しない値を提供し、プログラムクラッシュを引き起こします。
  • 過剰なリソース消費を引き起こします。
  • 機密データを読み取ります。
  • 悪意のある入力を使用して、データを変更したり制御フローを改めたりします。
  • 任意のコマンドを実行します。

脆弱コード例 1

コピー
   using System;
   using System.IO;
   namespace TaintedResource
   {
     class TestTaintedResource
     {
       const string fileName = "File.dat";
   
       public static void TaintedResourceExample1()
      {
              int num = getTaintedData();
        for(int i = 0; i < num; i++)
        {
           Test obj = new Test();     // CS.SV.TAINTED.LOOP_BOUND.RESOURCE
        }
      }
  
      public static int getTaintedData()
      {
        try
        {
          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
          {
            return(br.ReadInt32());
          }
        }
        catch (Exception e)
        {
          Console.WriteLine(e);
        }
      }
    }
    class Test
    {
      ---
      ---
    }
  }

Klocwork は 14 行目で CS.SV.TAINTED.LOOP_BOUND.RESOURCE の欠陥を報告します。これは、11 行目で「getTaintedData」の呼び出しを通じて受け取った、未検証の整数「num」が、12 行目でループ条件に使用される可能性があり、限られたリソースの無制御の消費を引き起こす可能性のある無限ループ内に、タイプ「Test」のオブジェクトが割り当てられていることを示しています。この場合、汚染されている可能性のあるデータがループ境界として使用されます。これは、悪意のあるユーザーによって悪用される可能性があります。

修正コード例 1

コピー
   using System;
   using System.IO;
   namespace TaintedResource
   {
     class TestTaintedResource
     {
       const string fileName = "File.dat";
   
       public static void TaintedResourceExample1()
      {
              int num = getTaintedData();
        if (num > MAX_ALLOCATION_QUOTA_IN_ONE_GO)
        {
           return;
        }
        for(int i = 0; i < num; i++)
        {
           Test obj = new Test();
        }
      }
  
      public static int getTaintedData()
      {
        try
        {
          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
          {
            return(br.ReadInt32());
          }
        }
        catch (Exception e)
        {
          Console.WriteLine(e);
        }
      }
    }
    class Test
    {
      ---
      ---
    }
  }

整数「num」はループ条件として使用される前に 12 行目でチェックされるので、Klocwork は欠陥を報告しなくなります。

脆弱コード例 2

コピー
   using System;
   using System.IO;
   namespace TaintedResource
   {
     class TestTaintedResource
     {
       const string fileName = "File.dat";
   
       public static void TaintedResourceExample1()
      {
              int num = getTaintedData();
        for(int i = 0; i < num; i++)
        {
           Test obj = new { X=1, Y=2, ---};     // CS.SV.TAINTED.LOOP_BOUND.RESOURCE
        }
      }
  
      public static int getTaintedData()
      {
        try
        {
          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
          {
            return(br.ReadInt32());
          }
        }
        catch (Exception e)
        {
          Console.WriteLine(e);
        }
      }
    }
    class Test
    {
      ---
      ---
    }
  }

Klocwork は 14 行目で CS.SV.TAINTED.LOOP_BOUND.RESOURCE の欠陥を報告します。これは、11 行目で「getTaintedData」の呼び出しを通じて受け取った、未検証の整数「num」が、12 行目でループ条件に使用される可能性があり、限られたリソースの無制御の消費を引き起こす可能性のある無限ループ内に、タイプ「<anonymous type>」のオブジェクトが割り当てられていることを示しています。この場合、汚染されている可能性のあるデータがループ境界として使用されます。これは、悪意のあるユーザーによって悪用される可能性があります。

修正コード例 2

コピー
   using System;
   using System.IO;
   namespace TaintedResource
   {
     class TestTaintedResource
     {
       const string fileName = "File.dat";
   
       public static void TaintedResourceExample1()
      {
              int num = getTaintedData();
        if (num > MAX_ALLOCATION_QUOTA_IN_ONE_GO)
        {
           return;
        }
        for(int i = 0; i < num; i++)
        {
           Test obj = new { X=1, Y=2, ---};
        }
      }
  
      public static int getTaintedData()
      {
        try
        {
          using (BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open)))
          {
            return(br.ReadInt32());
          }
        }
        catch (Exception e)
        {
          Console.WriteLine(e);
        }
      }
    }
    class Test
    {
      ---
      ---
    }
  }

整数「num」はループ終了条件として使用される前に 12 行目でチェックされるので、Klocwork は欠陥を報告しなくなります。