もう 1 つの懸念事項は、競合状態によって悪用されるセキュリティ ホールの可能性です。 この問題は、いくつかの方法で発生する可能性があります。 次のサブトピックでは、開発者が回避する必要がある主な落とし穴の一部を示します。
Dispose メソッドの競合状態
クラスの Dispose メソッド (詳細については、「 ガベージ コレクション」を参照) が同期されていない場合、次の例に示すように、 Dispose 内のクリーンアップ コードを複数回実行できる可能性があります。
Sub Dispose()
If Not (myObj Is Nothing) Then
Cleanup(myObj)
myObj = Nothing
End If
End Sub
void Dispose()
{
if (myObj != null)
{
Cleanup(myObj);
myObj = null;
}
}
この Dispose 実装は同期されないため、Cleanup
が _myObj
に設定される前に、最初の 1 つのスレッドと 2 番目のスレッドによってを呼び出す可能性があります。 これがセキュリティ上の問題であるかどうかは、 Cleanup
コードの実行時に何が起こるかによって異なります。 同期されていない Dispose 実装の主な問題は、ファイルなどのリソース ハンドルの使用です。 不適切な破棄により、間違ったハンドルが使用される可能性があり、多くの場合、セキュリティの脆弱性につながります。
コンストラクターの競合状態
アプリケーションによっては、クラス コンストラクターが完全に実行される前に、他のスレッドがクラス メンバーにアクセスできる場合があります。 これが発生する必要がある場合は、すべてのクラス コンストラクターを確認してセキュリティの問題がないことを確認するか、必要に応じてスレッドを同期する必要があります。
キャッシュされたオブジェクトの競合状態
次の例に示すように、クラスの他の部分が適切に同期されていない場合、セキュリティ情報をキャッシュしたり、コード アクセス セキュリティ Assert 操作を使用したりするコードも競合状態に対して脆弱になる可能性があります。
Sub SomeSecureFunction()
If SomeDemandPasses() Then
fCallersOk = True
DoOtherWork()
fCallersOk = False
End If
End Sub
Sub DoOtherWork()
If fCallersOK Then
DoSomethingTrusted()
Else
DemandSomething()
DoSomethingTrusted()
End If
End Sub
void SomeSecureFunction()
{
if (SomeDemandPasses())
{
fCallersOk = true;
DoOtherWork();
fCallersOk = false;
}
}
void DoOtherWork()
{
if (fCallersOK)
{
DoSomethingTrusted();
}
else
{
DemandSomething();
DoSomethingTrusted();
}
}
同じオブジェクトを持つ別のスレッドから呼び出すことができる DoOtherWork
への他のパスがある場合、信頼されていない呼び出し元が要求を超える可能性があります。
コードがセキュリティ情報をキャッシュする場合は、この脆弱性を確認してください。
ファイナライザーの競合状態
競合状態は、ファイナライザーで解放される静的リソースまたはアンマネージ リソースを参照するオブジェクトでも発生する可能性があります。 クラスのファイナライザーで操作されるリソースを複数のオブジェクトが共有する場合、オブジェクトはそのリソースへのすべてのアクセスを同期する必要があります。
こちらも参照ください
.NET