CA2119: Methoden versiegeln, die die Bedingungen privater Schnittstellen erfüllen
TypeName |
SealMethodsThatSatisfyPrivateInterfaces |
CheckId |
CA2119 |
Kategorie (Category) |
Microsoft.Security |
Unterbrechende Änderung |
Breaking |
Ursache
Ein vererbbarer öffentlicher Typ stellt eine überschreibbare Methodenimplementierung einer internal-Schnittstelle bereit (Friend in Visual Basic).
Regelbeschreibung
Schnittstellenmethoden weisen öffentliche Zugriffsmöglichkeiten auf, die durch den Implementierungstyp nicht geändert werden können.Eine interne Schnittstelle erstellt einen Vertrag, der nicht außerhalb der Assembly, welche die Schnittstelle definiert, implementiert werden soll.Durch einen öffentlichen Typ, der eine Methode einer internen Schnittstelle mithilfe des virtual-Modifizierers (Overridable in Visual Basic) implementiert, kann die Methode von einem abgeleiteten Typ, der sich außerhalb der Assembly befindet, überschrieben werden.Wenn ein zweiter Typ in der definierenden Assembly die Methode aufruft und einen nur intern zu implementierenden Vertrag erwartet, wird das Verhalten möglicherweise beeinträchtigt, wenn stattdessen die überschriebene Methode in der externen Assembly ausgeführt wird.Auf diese Weise entsteht ein Sicherheitsrisiko.
Behandeln von Verstößen
Um einen Verstoß gegen diese Regel zu beheben, verhindern Sie mit einem der folgenden Schritte, dass die Methode außerhalb der Assembly überschrieben wird:
Erstellen Sie den deklarierenden Typ sealed (NotInheritable in Visual Basic).
Ändern Sie die Zugriffsart des deklarierenden Typs in internal (Friend in Visual Basic).
Entfernen Sie alle öffentlichen Konstruktoren von dem deklarierenden Typ.
Implementieren Sie die Methode ohne den virtual-Modifizierer.
Implementieren Sie die Methode explizit.
Wann sollten Warnungen unterdrückt werden?
Warnungen dieser Regel können gefahrlos unterdrückt werden, wenn nach sorgfältiger Überprüfung keine Sicherheitslücken mehr vorhanden sind, die ausgenutzt werden können, wenn die Methode außerhalb der Assembly überschrieben wird.
Beispiel
Im folgenden Beispiel wird ein Typ veranschaulicht, BaseImplementation, der gegen diese Regel verstößt.
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.");
}
}
};
}
Im folgenden Beispiel wird die virtuelle Methodenimplementierung des vorherigen Beispiels ausgenutzt.
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.");
}
}
};
}
Siehe auch
Referenz
Schnittstellen (C#-Programmierhandbuch)