CS.SV.TAINTED.CALL.LOOP_BOUND.RESOURCE
汚染されたデータによって終了条件が制御されるループ内でのリソース割り当て
入力がユーザーまたは外部環境から受け入れられるときは常に、入力のタイプ、長さ、書式、および範囲を検証してから使用する必要があります。適切に検証されるまでは、そのデータは汚染していると言われます。CS.SV.TAINTED ファミリーのチェッカーは、コードでの汚染データの使用箇所を探します。
CS.SV.TAINTED.CALL.LOOP_BOUND.RESOURCE チェッカーは、あるループ内で (マネージドまたはアンマネージドの) リソースが割り当てられている間にループ境界として使用される関数に、未検証の整数データを呼び出し引数として渡すコードにフラグを立てます。
ループ本体の最後でリソースへの参照が残っていない場合、一部のリソースはガベージコレクターによってすぐに破棄される可能性がありますが、そのような破棄のタイミングは保証されません。さらに、割り当てられたリソースのなかには存続期間が長くなるものがあり、その結果、リソースが過剰に消費され、リソースを使い果たすかプログラムが失敗する可能性があります。この動作は、このようなループからの終了条件が外部入力によって制御されるときに、潜在的な攻撃者によって悪用される可能性があります。
脆弱性とリスク
コードへの入力が適切に検証されないと、攻撃者は入力をアプリケーションが予期しない形で作成することができます。意図しない入力を受け取ると、制御フローの改変、任意リソースの制御、および任意のコードの実行につながる可能性があります。この種のチャンスがある場合、攻撃者は次のことを行えます。
- 予期しない値を提供し、プログラムクラッシュを引き起こします。
- 過剰なリソース消費を引き起こします。
- 機密データを読み取ります。
- 悪意のある入力を使用して、データを変更したり制御フローを改めたりします。
- 任意のコマンドを実行します。
脆弱コード例
using System;
using System.IO;
namespace TaintedResource {
class TestTaintedResource {
const string fileName = "File.dat";
public static void TaintedResourceExample1() {
int num = getTaintedData();
sinkMethod(num); // CS.SV.TAINTED.CALL.LOOP_BOUND.RESOURCE
}
public static void sinkMethod(int value) {
for(int i = 0; i < value; 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
{
---
---
}
}
Klocwork は 14 行目で指摘レポートを生成し、「1 つ以上のオブジェクトがループ本体内に割り当てられており、その終了条件は 9 行目の 'sinkMethod' の呼び出しを通じて未検証の整数値 'taintedIntValue' によって制御されている」ことを示します。この場合、汚染されている可能性のあるデータがループ境界として使用されます。これは、悪意のあるユーザーによって悪用される可能性があります。
修正コード例
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;
}
sinkMethod(num);
}
public static void sinkMethod(int value) {
for(int i = 0; i < value; 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 はもはや欠陥を報告しません。