Share via


Seguridad y condiciones de carrera

Otra área de preocupación es la posibilidad de vulnerabilidades de seguridad aprovechadas por las condiciones de carrera. Esto puede suceder de varias formas. Los subtemas que siguen describen algunos de los principales problemas que debe evitar el desarrollador.

Condiciones de carrera en el método Dispose

Si el método Dispose de una clase (para más información, consulte Recolección de elementos no utilizados) no está sincronizado, es posible que el código de limpieza dentro de Dispose se pueda ejecutar más de una vez, como se muestra en el ejemplo siguiente.

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

Dado que esta implementación de Dispose no está sincronizada, es posible que un subproceso llame primero a Cleanup y, a continuación lo haga un segundo subproceso antes de que _myObj se establezca en null. Si esto supone un problema de seguridad o no depende de lo que suceda cuando se ejecute el código Cleanup. Un problema importante con las implementaciones de Dispose no sincronizadas implica el uso de identificadores de recursos como archivos. La eliminación incorrecta puede hacer que se use el identificador incorrecto, lo que a menudo conduce a vulnerabilidades de seguridad.

Condiciones de carrera en constructores

En algunas aplicaciones, es posible que otros subprocesos accedan a los miembros de clase antes de que sus constructores de clase se hayan ejecutado por completo. Debe revisar todos los constructores de clase para asegurarse de que no haya ningún problema de seguridad si esto sucediera, o sincronizar los subprocesos si es necesario.

Condiciones de carrera con objetos almacenados en caché

El código que almacena en caché la información de seguridad o usa la operación Assert de seguridad de acceso del código también podría ser vulnerable a las condiciones de carrera si otras partes de la clase no están sincronizadas correctamente, como se muestra en el ejemplo siguiente.

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

Si hay otras rutas de acceso a DoOtherWork a las que se puede llamar desde otro subproceso con el mismo objeto, un llamador que no es de confianza puede deslizarse detrás de una petición.

Si el código almacena en caché la información de seguridad, asegúrese de revisarla para esta vulnerabilidad.

Condiciones de carrera en finalizadores

Las condiciones de carrera también pueden producirse en un objeto que hace referencia a un recurso estático o no administrado que luego libera en su finalizador. Si varios objetos comparten un recurso que se manipula en el finalizador de una clase, los objetos deben sincronizar todos los accesos a ese recurso.

Consulte también