Condividi tramite


Condizioni di sicurezza e di gara

Un'altra area di preoccupazione è il potenziale di vulnerabilità di sicurezza sfruttate dalle condizioni di gara. Ci sono diversi modi in cui questo potrebbe accadere. Gli argomenti secondari che seguono delineano alcune delle principali insidie che lo sviluppatore deve evitare.

Condizioni di gara nel metodo Dispose

Se il metodo Dispose di una classe (per altre informazioni, vedere Garbage Collection) non è sincronizzato, è possibile che il codice di pulizia all'interno di Dispose possa essere eseguito più volte, come illustrato nell'esempio seguente.

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

Poiché questa implementazione dispose non è sincronizzata, è possibile Cleanup chiamare da un primo thread e quindi un secondo thread prima _myObj di essere impostato su Null. Se si tratta di un problema di sicurezza dipende da ciò che accade quando viene eseguito il Cleanup codice. Un problema importante con le implementazioni dispose non sincronizzate implica l'uso di handle di risorse come i file. L'eliminazione non corretta può causare l'uso dell'handle errato, che spesso causa vulnerabilità di sicurezza.

Condizioni di corsa nei Costruttori

In alcune applicazioni, potrebbe essere possibile che altri thread accedano ai membri della classe prima che i costruttori della classe abbiano terminato completamente la loro esecuzione. È consigliabile esaminare tutti i costruttori di classi per assicurarsi che non siano presenti problemi di sicurezza, se necessario, o sincronizzare i thread.

Condizioni di gara con oggetti memorizzati nella cache.

Il codice che memorizza nella cache le informazioni di sicurezza o usa l'operazione Assert per l'accesso al codice potrebbe anche essere vulnerabile alle race condition se altre parti della classe non sono sincronizzate in modo appropriato, come illustrato nell'esempio seguente.

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

Se ci sono altri percorsi verso DoOtherWork che possono essere chiamati da un altro thread con lo stesso oggetto, un chiamante non attendibile può eludere una richiesta.

Se il codice memorizza nella cache le informazioni di sicurezza, assicurarsi di esaminarlo per questa vulnerabilità.

Condizioni di gara nei finalizzatori

Le condizioni di gara possono verificarsi anche in un oggetto che fa riferimento a una risorsa statica o non gestita, che viene poi liberata nel suo finalizzatore. Se più oggetti condividono una risorsa modificata nel finalizzatore di una classe, gli oggetti devono sincronizzare tutti gli accessi a tale risorsa.

Vedere anche