CA2119: プライベート インターフェイスを満たすメソッドをシールします
TypeName |
SealMethodsThatSatisfyPrivateInterfaces |
CheckId |
CA2119 |
カテゴリ |
Microsoft.Security |
互換性に影響する変更点 |
あり |
原因
継承可能なパブリック型により、internal (Visual Basic では Friend) インターフェイスのオーバーライド可能なメソッド実装が提供されます。
規則の説明
インターフェイス メソッドにはパブリック アクセシビリティがあります。実装する型によるアクセシビリティの変更はできません。 内部インターフェイスでは、インターフェイスを定義するアセンブリの外部に実装することを目的としていないコントラクトが作成されます。 virtual (Visual Basic では Overridable) 修飾子を使用して内部インターフェイスのメソッドを実装するパブリック型により、メソッドをアセンブリの外部にある派生型でオーバーライドできます。 アセンブリの定義における 2 番目の型によりメソッドが呼び出され、内部限定のコントラクトが想定されている場合に、外部のアセンブリでオーバーライドされたメソッドが実行されると、処理が危険にさらされる可能性があります。 これにより、セキュリティの脆弱性が発生します。
違反の修正方法
この規則違反を修正するには、次のいずれかの方法を使用してアセンブリ外部でメソッドがオーバーライドされないようにします。
宣言している型を sealed (Visual Basic では NotInheritable) にします。
宣言している型のアクセシビリティを internal (Visual Basic では Friend) に変更します。
宣言している型からパブリック コンストラクターをすべて削除します。
virtual 修飾子を使用せずに、メソッドを実装します。
メソッドを明示的に実装します。
警告を抑制する状況
メソッドがアセンブリの外部でオーバーライドされる場合、悪用される可能性があるセキュリティ問題が存在しないことを注意深く確認すれば、この規則による警告を抑制しても安全です。
使用例
この規則に違反する型である BaseImplementation を次の例に示します。
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.");
}
}
};
}
次に示す例では、前の例の仮想メソッドの実装を悪用しています。
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.");
}
}
};
}