CA2153:破損状態の例外の処理を回避する

プロパティ
ルール ID CA2153
Title 破損状態の例外の処理を回避する
[カテゴリ] Security
修正が中断か中断なしであるか なし
.NET 8 では既定で有効 いいえ

原因

破損状態例外 (CSE) は、メモリの破損がプロセス内に存在していることを示します。 プロセスをクラッシュさせるのではなくこれらの例外をキャッチすることは、攻撃者が破損したメモリ領域にセキュリティ上の弱点を見出すことができた場合に、セキュリティ上の脆弱性となる可能性があります。

規則の説明

CSE は、プロセスが破損状態にあり、システムによってキャッチされていないことを示します。 破損した状態のシナリオでは、System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute 属性でメソッドをマークした場合に、汎用ハンドラーのみがこの例外をキャッチします。 既定では、共通言語ランタイム (CLR) は、CSE の catch ハンドラーを呼び出しません。

最も安全な方法は、この種の例外をキャッチせずにプロセスをクラッシュさせることです。 コードをログに記録しても、攻撃者はメモリ破損のバグを悪用できます。

catch (System.Exception e) や例外パラメーターを持たない catch などすべての例外をキャッチする汎用ハンドラーを使用して CSE をキャッチすると、この警告がトリガーされます。

違反の修正方法

この警告を解決するには、次のいずれかの操作を行います:

  • HandleProcessCorruptedStateExceptionsAttribute 属性を削除してください。 これにより、CSE を catch ハンドラーに渡さない既定の実行時の動作に戻ります。

  • 特定の例外の種類をキャッチするハンドラーではなく汎用 catch ハンドラーを削除します。 ハンドラー コードが安全に処理できたと仮定した場合 (まれ)、これに CSE が含まれることがあります。

  • 例外を呼び出し元に渡し、実行中のプロセスを終了させる catch ハンドラーで CSE を再スローします。

どのようなときに警告を抑制するか

この規則による警告は抑制しないでください。

擬似コードの例

違反

次の擬似コードでは、このルールにより検出されたパターンを示しています。

[HandleProcessCorruptedStateExceptions]
// Method that handles CSE exceptions.
void TestMethod1()
{
    try
    {
        FileStream fileStream = new FileStream("name", FileMode.Create);
    }
    catch (Exception e)
    {
        // Handle exception.
    }
}

解決策 1 - 属性を削除する

HandleProcessCorruptedStateExceptionsAttribute 属性を削除すると、メソッドによって破損状態の例外が処理されなくなります。

void TestMethod1()
{
    try
    {
        FileStream fileStream = new FileStream("name", FileMode.Create);
    }
    catch (Exception e)
    {
        // Handle exception.
    }
}

解決策 2 - 特定の例外をキャッチする

汎用 catch ハンドラーを削除し、特定の例外の種類のみをキャッチします。

void TestMethod1()
{
    try
    {
        FileStream fileStream = new FileStream("name", FileMode.Create);
    }
    catch (IOException e)
    {
        // Handle IOException.
    }
    catch (UnauthorizedAccessException e)
    {
        // Handle UnauthorizedAccessException.
    }
}

解決策 3 - 再スローする

例外を再スローします。

[HandleProcessCorruptedStateExceptions]
void TestMethod1()
{
    try
    {
        FileStream fileStream = new FileStream("name", FileMode.Create);
    }
    catch (Exception e)
    {
        // Rethrow the exception.
        throw;
    }
}