Partage via


Conditions de sécurité et de course

Un autre sujet de préoccupation concerne les failles de sécurité susceptibles d'être exploitées par des conditions de concurrence. Il existe plusieurs façons de procéder. Les sous-rubriques qui suivent décrivent certains des principaux pièges que le développeur doit éviter.

Conditions de concurrence dans la méthode Dispose

Si la méthode Dispose d’une classe (pour plus d’informations, voir Garbage Collection) n’est pas synchronisée, il est possible que le code de nettoyage à l’intérieur de Dispose puisse être exécuté plusieurs fois, comme illustré dans l’exemple suivant.

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

Étant donné que cette implémentation Dispose n’est pas synchronisée, il est possible qu'un premier thread appelle Cleanup, puis qu'un deuxième thread le fasse avant que _myObj ne soit défini sur null. La question de savoir s’il s’agit d’une préoccupation de sécurité dépend de ce qui se passe lorsque le Cleanup code s’exécute. Un problème majeur lié aux implémentations de suppression non synchronisées implique l’utilisation de handles de ressources tels que des fichiers. Une élimination inappropriée peut entraîner l'utilisation d'un handle inadapté, ce qui conduit souvent à des failles de sécurité.

Conditions de course dans les constructeurs

Dans certaines applications, il est possible que d'autres threads accèdent aux membres d'une classe avant que les constructeurs de cette classe aient complètement terminé leur exécution. Vous devez passer en revue tous les constructeurs de classe pour vous assurer qu’il n’y a aucun problème de sécurité si cela doit se produire ou synchroniser les threads si nécessaire.

Conditions de concurrence avec des objets mis en cache

Le code qui met en cache les informations de sécurité ou utilise l’opération Assert de sécurité d’accès au code peut également être vulnérable aux conditions de concurrence si d’autres parties de la classe ne sont pas correctement synchronisées, comme illustré dans l’exemple suivant.

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

S'il existe d'autres chemins d'accès à DoOtherWork pouvant être appelés depuis un autre thread avec le même objet, un appelant non approuvé peut contourner une exigence.

Si votre code met en cache les informations de sécurité, assurez-vous de l’examiner pour cette vulnérabilité.

Conditions de concurrence dans les finaliseurs

Les conditions de concurrence peuvent également se produire dans un objet qui fait référence à une ressource statique ou non managée qu’elle libère ensuite dans son finaliseur. Si plusieurs objets partagent une ressource qui est manipulée dans le finaliseur d’une classe, les objets doivent synchroniser tous les accès à cette ressource.

Voir aussi