InternalsVisibleTo - 如何防止某人创建具有相同名称的程序集并访问内部 类 或方法?

InternalsVisibleTo - How do you prevent someone from creating an assembly with same name and get access to internal classes or methods?

最近,我发现了使内部 类 和方法对其他程序集可见的 InternalsVisibleTo 方法。虽然这在您拥有一大堆程序集并且希望避免循环依赖或代码重复的应用程序中非常有用,但我们中的一些人认为这可能会暴露安全漏洞。你有什么想法?

例如,如果我有这样的属性:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("foo")]

即使它隐藏在 assemblyInfo.cs 文件中,也可以通过反汇编等方式发现它。并不是每个人都对他们的程序集进行签名或混淆。现在,有了可能有更多功能可供使用的信息,我可以创建自己的名为 foo.dll 的程序集,然后使用我以前无法使用的 methods/classes。

这里没有安全漏洞,因为 public/private 区别与安全无关。出于安全原因,成员 "hidden" 不是私有成员,而是出于设计原因。任何人都可以通过反射找到你所有的私有方法并直接调用它们,即使 InternalsVisibleTo 没有设置。

如果可以的话,您应该首先避免使用 InternalsVisibleTo。我什至很少在类型上使用 internal 可访问性,甚至很少发现这些类型需要被声明它们的程序集以外的程序集访问。

也就是说,该属性确实存在是有原因的,并且在极少数情况下确实需要它。在那些情况下,正如您所发现的,如果引用的程序集未签名,那么任何人都可以构建这样的程序集,然后您自己的程序集中的内部结构将对它可见。

不,您对此无能为力。 .NET 无法识别 "correct" 程序集,除非它已签名。这正是 存在签名的原因。

所以,如果你真的想限制对程序集内部成员的访问,那么你需要使用强命名(即签署程序集),以便 .NET 可以区分正确的程序集和不正确的程序集。冒名顶替者。

如果您不想 "accidental" 替换(我不小心说是因为成员可见性不是安全措施),您需要使用 strong name signing of the target assembly you are wanting to make visible (your source assembly will also need to be strong named, see the remarks section of the MSDN for InternalsVisibleToAttribute)。

所以下面的属性

[assembly: InternalsVisibleTo("foo")]

会变成

[assembly: InternalsVisibleTo("foo, PublicKey=002400000480000094" + 
                              "0000000602000000240000525341310004000" +
                              "001000100bf8c25fcd44838d87e245ab35bf7" +
                              "3ba2615707feea295709559b3de903fb95a93" +
                              "3d2729967c3184a97d7b84c7547cd87e435b5" +
                              "6bdf8621bcb62b59c00c88bd83aa62c4fcdd4" +
                              "712da72eec2533dc00f8529c3a0bbb4103282" +
                              "f0d894d5f34e9f0103c473dce9f4b457a5dee" +
                              "fd8f920d8681ed6dfcb0a81e96bd9b176525a" +
                              "26e0b3"")]

然后只有使用与属性中列出的 public 密钥相对应的私钥签名的程序集才能查看程序集的内部信息。

我的经验是 InternalsVisibleTo 对声音单元测试必不可少。

我同意之前的回答,即字符串名称签名是最小化安全漏洞的关键。如果你想要双重安全 - 我在 InternalsVisibleTo 声明周围包装了一个 (#IF DEBUG)。然后你去RELEASE的时候不编译。