Sicurezza e race condition

Un'altra area di preoccupazione è il potenziale per i buchi di sicurezza sfruttati da race condition. Ci sono diversi modi in cui questo potrebbe accadere. Gli argomenti secondari che seguono delineano alcune delle principali insidie che lo sviluppatore deve evitare.

Race Conditions 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 che Cleanup venga chiamato da un primo thread e quindi da un secondo thread prima che _myObj sia impostato su null. Se si tratta di un problema di sicurezza dipende da ciò che accade quando viene eseguito il codice Cleanup. 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.

Race Conditions in Costruttori

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

Race Conditions con Oggetti memorizzati nella cache

Il codice che memorizza nella cache le informazioni di sicurezza o usa l’operazione di sicurezza dell'accesso al codice Assert 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 sono presenti altri percorsi per DoOtherWork che possono essere chiamati da un altro thread con lo stesso oggetto, un chiamante non attendibile può scivolare oltre una richiesta.

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

Race Conditions nei Finalizzatori

Le race condition possono verificarsi anche in un oggetto che fa riferimento a una risorsa statica o non gestita che poi libera 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.

Vedi anche