6

我们在 ASP.NET 应用程序中调用 System.IO.Packaging.Package.Open()。此外,在调用它之前已执行 Windows 模拟,因为要打开的包存储在安全位置,并且需要模拟才能读取它。

问题是Package.Open()调用 EventTrace.EasyTraceEvent() ,后者又调用MS.Utility.EventTrace.IsClassicETWRegistryEnabled(),这会引发不允许请求注册表访问的安全异常。

即使在 Web.config 中特别禁用,也会发生这种情况。在调试和发布模式下。

因此我的困境。模拟是必需的,因为文件(包)的存储方式只能由模拟帐户访问。将其复制到不安全的位置会破坏安全性的目的。

授予模拟帐户对注册表的访问权限会在另一个方向上打开一个安全漏洞。除了一组特定的文件和文件夹之外,此帐户没有也不需要访问任何其他系统资源。

我真正想要的是让 EventTrace 从悬崖上飞跃,但我不知道如何告诉它这样做。

有任何想法吗?

4

2 回答 2

3

简短的回答:使用流。进行模拟以打开流,结束模拟,然后将仍然打开的流传递给 Package.Open()。

长答案:

  • 错误的来源是EventTrace的静态类初始化程序。它调用 IsClassicETWRegistryEnabled() 依次访问注册表。由于它在类初始化程序中,这意味着无法禁用它,并且 EventTrace 在涉及模拟时从根本上被破坏了。

  • Package.Open() 实际上是“new ZipPackage()”的包装。

  • ZipPackage 是 Package 抽象类的密封实现。

  • ZipPackage 没有公共构造函数。

  • ZipPackage 反过来使用ZipArchive上的内部方法,该方法位于 MS.Internal.IO.Zip 命名空间中,也是一个密封类。

结论:

  • 当模拟没有足够的注册表访问权限时,System.IO.Packaging 会出现模拟问题。

  • System.IO.Packaging 应被视为私有 Microsoft 命名空间,而不是公共命名空间。

选项:

  • 将文件移出安全区域,这样就不需要冒充了。

  • 在不需要模拟时加载文件并以其他方式存储数据(例如:在数据库中)。

  • 打开模拟下的流,结束模拟,然后在流上使用 Package.Open()。

如果有人好奇,我们正在阅读的软件包是 Visio 2013 VSDX 文件。

于 2014-09-12T21:30:59.423 回答
0

我查看了 .NET 源参考,它需要访问的键是 HKEY_CURRENT_USER\Software\Microsoft\Avalon.Graphics。授予“每个人”对该特定密钥的读取访问权限没有我能想到的安全隐患,并解决了问题。

于 2020-04-08T16:16:47.757 回答