Teilen über


Sicherheit und Racebedingungen

Ein weiterer Problembereich ist das Potenzial für Sicherheitslücken, die durch Racebedingungen ausgenutzt werden. Dies kann auf verschiedene Arten erfolgen. Die nachfolgenden Unterthemen beschreiben einige der wichtigsten Probleme, die Entwickler vermeiden müssen.

Racebedingungen in der Dispose-Methode

Wenn die Dispose-Methode einer Klasse (weitere Informationen finden Sie unter Garbage Collection) nicht synchronisiert ist, kann der Bereinigungscode in Dispose u. U. mehr als einmal ausgeführt werden kann, wie im folgenden Beispiel gezeigt.

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;  
    }  
}  

Da diese Dispose-Implementierung nicht synchronisiert ist, kann Cleanup zuerst von einem und dann von einem zweiten Thread aufgerufen werden, bevor _myObj auf NULL festgelegt wird. Ob dies ein Sicherheitsproblem ist, hängt davon ab, was geschieht, wenn der Cleanup-Code ausgeführt wird. Eines der größeren Probleme bei nicht synchronisierten Dispose-Implementierungen ist die Verwendung von Ressourcenhandles wie Dateien. Eine unsachgemäße Löschung kann dazu führen, dass der falsche Handle verwendet wird, was häufig zu Sicherheitsrisiken führt.

Racebedingungen in Konstruktoren

In einigen Anwendungen können andere Threads u. U. auf Klassenmember zugreifen, bevor die Klassenkonstruktoren vollständig ausgeführt wurden. Überprüfen Sie alle Klassenkonstruktoren, um sicherzustellen, dass es in diesem Fall keine Sicherheitsprobleme gibt. Alternativ können Sie die Threads bei Bedarf synchronisieren.

Racebedingungen mit zwischengespeicherten Objekten

Code, der Sicherheitsinformationen zwischenspeichert oder den Assert-Vorgang für die Codezugriffssicherheit verwendet, kann ebenfalls anfällig für Racebedingungen sein, wenn andere Teile der Klasse nicht entsprechend synchronisiert sind, wie im folgenden Beispiel gezeigt.

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();  
    }  
}  

Wenn andere Pfade zu DoOtherWork vorhanden sind, die von einem anderen Thread mit demselben Objekt aufgerufen werden können, kann ein nicht vertrauenswürdiger Aufrufer eine Anforderung umgehen.

Wenn Ihr Code Sicherheitsinformationen zwischenspeichert, stellen Sie sicher, dass er nicht für dieses Problem anfällig ist.

Racebedingungen in Finalizern

Racebedingungen können auch in einem Objekt auftreten, das auf eine statische oder nicht verwaltete Ressource verweist, die dann in ihrem Finalizer freigegeben wird. Wenn mehrere Objekte eine Ressource gemeinsam nutzen, die im Finalizer einer Klasse bearbeitet wird, müssen die Objekte den gesamten Zugriff auf diese Ressource synchronisieren.

Siehe auch