CA2119 : Scellez les méthodes qui satisfont les interfaces privées
TypeName |
SealMethodsThatSatisfyPrivateInterfaces |
CheckId |
CA2119 |
Catégorie |
Microsoft.Security |
Modification avec rupture |
Oui |
Cause
Un type public pouvant être hérité fournit une implémentation de méthode pouvant être substituée d'une interface internal (Friend en Visual Basic).
Description de la règle
Les méthodes d'interface disposent d'une accessibilité publique, qui ne peut pas être modifiée par le type d'implémentation. Une interface interne crée un contrat qui n'est pas destiné à être implémenté à l'extérieur de l'assembly qui définit l'interface. Un type public qui implémente une méthode d'une interface interne à l'aide du modificateur virtual (Overridable en Visual Basic) autorise la substitution de la méthode par un type dérivé situé à l'extérieur de l'assembly. Si un deuxième type dans l'assembly de définition appelle la méthode et s'attend à un contrat interne uniquement, le comportement peut être compromis lorsque la méthode substituée dans l'assembly externe est exécutée. Cela crée une faille de sécurité.
Comment corriger les violations
Pour corriger une violation de cette règle, empêchez la substitution de la méthode à l'extérieur de l'assembly à l'aide de l'une des méthodes suivantes :
Créez le type déclarant sealed (NotInheritable en Visual Basic).
Remplacez l'accessibilité du type déclarant par internal (Friend en Visual Basic).
Supprimez tous les constructeurs publics du type déclarant.
Implémentez la méthode sans utiliser le modificateur virtual.
Implémentez explicitement la méthode.
Quand supprimer les avertissements
Il est possible de supprimer sans risque un avertissement de cette règle si, après examen minutieux, aucun problème de sécurité, qui peut être exploitable si la méthode est substituée à l'extérieur de l'assembly, n'est détecté.
Exemple
L'exemple suivant présente un type, BaseImplementation, qui ne respecte pas cette règle.
Imports System
Namespace SecurityLibrary
Interface IValidate
Function UserIsValidated() As Boolean
End Interface
Public Class BaseImplementation
Implements IValidate
Overridable Function UserIsValidated() As Boolean _
Implements IValidate.UserIsValidated
Return False
End Function
End Class
Public Class UseBaseImplementation
Sub SecurityDecision(someImplementation As BaseImplementation)
If(someImplementation.UserIsValidated() = True)
Console.WriteLine("Account number & balance.")
Else
Console.WriteLine("Please login.")
End If
End Sub
End Class
End Namespace
using System;
namespace SecurityLibrary
{
// Internal by default.
interface IValidate
{
bool UserIsValidated();
}
public class BaseImplementation : IValidate
{
public virtual bool UserIsValidated()
{
return false;
}
}
public class UseBaseImplementation
{
public void SecurityDecision(BaseImplementation someImplementation)
{
if(someImplementation.UserIsValidated() == true)
{
Console.WriteLine("Account number & balance.");
}
else
{
Console.WriteLine("Please login.");
}
}
}
}
using namespace System;
namespace SecurityLibrary
{
// Internal by default.
interface class IValidate
{
bool UserIsValidated();
};
public ref class BaseImplementation : public IValidate
{
public:
virtual bool UserIsValidated()
{
return false;
}
};
public ref class UseBaseImplementation
{
public:
void SecurityDecision(BaseImplementation^ someImplementation)
{
if(someImplementation->UserIsValidated() == true)
{
Console::WriteLine("Account number & balance.");
}
else
{
Console::WriteLine("Please login.");
}
}
};
}
L'exemple suivant exploite l'implémentation de méthode virtuelle de l'exemple précédent.
Imports System
Namespace SecurityLibrary
Public Class BaseImplementation
Overridable Function UserIsValidated() As Boolean
Return False
End Function
End Class
Public Class UseBaseImplementation
Sub SecurityDecision(someImplementation As BaseImplementation)
If(someImplementation.UserIsValidated() = True)
Console.WriteLine("Account number & balance.")
Else
Console.WriteLine("Please login.")
End If
End Sub
End Class
End Namespace
using System;
namespace SecurityLibrary
{
public class BaseImplementation
{
public virtual bool UserIsValidated()
{
return false;
}
}
public class UseBaseImplementation
{
public void SecurityDecision(BaseImplementation someImplementation)
{
if (someImplementation.UserIsValidated() == true)
{
Console.WriteLine("Account number & balance.");
}
else
{
Console.WriteLine("Please login.");
}
}
}
}
using namespace System;
namespace SecurityLibrary
{
public ref class BaseImplementation
{
public:
virtual bool UserIsValidated()
{
return false;
}
};
public ref class UseBaseImplementation
{
public:
void SecurityDecision(BaseImplementation^ someImplementation)
{
if(someImplementation->UserIsValidated() == true)
{
Console::WriteLine("Account number & balance.");
}
else
{
Console::WriteLine("Please login.");
}
}
};
}
Voir aussi
Référence
Interfaces (Guide de programmation C#)