安全性和競爭情形

另一個考慮範圍是競爭條件所惡意探索的安全性漏洞的可能性。 有幾種方式可能會發生這種情況。 後續的子主題概述開發人員所必須避免的一些主要陷阱。

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 設為 null。 這是否為安全性考量,取決於 Cleanup 程式碼執行時會發生什麼情況。 未同步處理的 Dispose 實作的主要問題牽涉到使用資源控制代碼,例如檔案。 不當處置可能會導致使用錯誤的控制代碼,這通常會導致安全性弱點。

建構函式中的競爭條件

在部份應用程式中,其他執行緒可能會在類別建構函式完全執行之前存取類別成員。 您應該檢閱所有類別建構函式,以確定發生此情況時沒有任何安全性問題,或視需要同步處理執行緒。

快取物件的競爭條件

如果類別的其他部分未適當同步處理,快取安全性資訊或使用程式碼存取安全性判斷提示作業的程式碼也可能容易受到競爭條件攻擊,如下列範例所示。

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 的其他路徑可從具有相同物件的另一個執行緒呼叫,則不受信任的呼叫者可能會滑動超過需求。

如果您的程式碼快取安全性資訊,請務必檢閱它是否有此弱點。

完成項中的競爭條件

競爭條件也可能發生在參考靜態或 Unmanaged 資源的物件中,然後它會釋放其完成項。 如果多個物件共用在類別的完成項中操作的資源,則物件必須同步處理該資源的所有存取權。

另請參閱