CS.SV.TAINTED.ALLOC_SIZE

メモリ割り当てで使用される未検証の入力

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

CS.SV.TAINTED.ALLOC_SIZE チェッカーが、汚染データを使用してメモリ割り当てのサイズを決定するコードにフラグを立てます。

脆弱性とリスク

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

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

ユーザーが指定した整数を使用してメモリを割り当てると、リソースが過剰に消費されかねません。ユーザーが極端に大きい整数を渡した場合、アプリケーションは極端に大量のメモリを割り当てます。これにより、アプリケーションはシステムメモリを消費し、システムが停止してサービス拒否 (DoS) 攻撃が引き起こされる可能性があります。

軽減と防止

汚染入力エラーを回避するには:

  • パラメーターや引数、クッキー、ネットワークから読み取られる入力、環境変数、逆 DNS ルックアップ、クエリ結果、ファイル名、データベース、および外部システムという、信頼されていない入力がソフトウェア内に入り込む可能性がある領域すべてを把握します。
  • ブラックリスト、つまり「既知の不良な」戦略だけを信頼するのではなく、ホワイトリスト、つまり「既知の良好な」ポリシーを入力に使用します。
  • 入力の該当するプロパティがすべて検証済みであることを確認します。これには、長さ、タイプ、範囲、欠落しているか余計な入力、構文、および一貫性が含まれます。
  • アプリケーションのクライアント側でセキュリティチェックが実行される場合、サーバー側で複製されることを確認します。
  • アプリケーションで複数ソースからの入力が組み合わされる場合、ソースの組み合わせが完了したら検証を行います。

脆弱コード例

コピー
   namespace myNamespace
   {    
       class AllocateBuffer
       {
           public static void TryAllocateBuffer()
           {            
               int input_value = Console.Read();
               int[] integerArray = new int[input_value]; 
    }
      }
  }

このコードでは、input_value は、Console.Read() の呼び出しを介してユーザー入力からコピーされ、検証なしに演算子 new へのオペランドとして使用されます。これは、任意の大きなメモリ割り当てを介して過剰なメモリ消費につながる可能性があります。Klocwork はこの脆弱性を CS.SV.TAINTED.ALLOC_SIZE の欠陥として報告します。

修正コード例

コピー
   namespace myNamespace
   {    
       class AllocateBuffer
       {
           public static void TryAllocateBuffer()
           {            
               int input_value = Console.Read();
   
            // Validate input before using it in a memory allocation 
           if (input_value > 0 && input_value <= MAX_BUFFER_SIZE)
           {
                  int[] integerArray = new int[input_value]; 
           }
          }
      }
  }

この例では、外部制御されたデータは 10 行目で検証後にのみ使用されるため、コードは任意のメモリ割り当て攻撃に対して脆弱ではなくなります。