【问题标题】:Log file possibly created with elevated privileges可能使用提升的权限创建的日志文件
【发布时间】:2010-11-09 15:46:18
【问题描述】:

我有一个非常旧的应用程序,现在需要对 Windows Server 2008 友好。它是一个作为单例工作的用户应用程序。它使用注册表的 HKLM 部分来读取和写入配置,并创建日志文件。

主要问题:就当前最佳实践而言,如何使应用程序与 UAC 一起工作?

我最初的方法是运行非提升的应用程序,如果需要更改配置,用户手动重新启动它提升,重新配置,然后重新启动到非提升。问题是日志文件也可以创建提升,然后非提升的应用程序不能写入它。可能的解决方法:

  1. 不要在提升模式下执行任何暗示写入日志文件的操作。但是如何检测应用程序是否处于提升模式?
  2. 即使在提升模式下也可以创建具有非提升权限的日志文件。怎么样?
  3. 如果在打开现有日志文件时访问被拒绝,请尝试创建另一个日志文件。
  4. 一直在高处跑步。

到目前为止,第一个选项看起来最好,但是如何检测海拔?也许还有其他选择?也许有一些完全不同的方法?如果可能的话,我希望不必过多地更改代码。

【问题讨论】:

    标签: windows visual-c++ registry uac


    【解决方案1】:

    最佳做法是重写应用程序以使用每个用户的存储空间,除非您确实需要某个用户保存的内容来影响盒子上的其他用户。即拒绝“只有一个用户,因此每用户和每机器相同”的答案。在这种情况下,整个应用程序始终以非提升方式运行,并带有防止虚拟化的清单。

    下一个最佳实践是对应用程序进行分区。写入 HKLM 的代码位于单独的 exe 中,并具有请求提升的清单。 UI 有一些警告(按钮或菜单项上的屏蔽),用户在其中运行此代码。单独的进程使用 ShellExecute 启动,它尊重清单。用户的体验是应用程序在大多数情况下运行时不会提升,有时它的某些部分似乎会提升然后下降。这就是它看起来的样子,但这实际上是不可能的——一个 exe 要么被提升,要么没有。你用两个 exe 来实现这个效果。

    第三个最好的方法是将日志移动到无论您是否提升都相同的位置,并训练您的用户在需要时手动提升。我认为这根本不是一个好的解决方案,但总比训练他们每次手动提升并在不同的地方写入日志文件要好。我猜你写在“当前目录”下,它本身就在 Program Files 下,而且你没有清单。然后,当没有提升时,您的应用程序将在虚拟商店下写入。如果用户需要查找日志文件,这确实不好。写入另一个文件夹 - AppData 下的东西会很好。该位置不会被虚拟化。

    检测您是否被提升的最简单方法是使用 IsInRole 查看用户是否为管理员。正如一个小测试所证明的那样,即使是管理员用户在应用未提升时​​也会返回false,即使是通过OTS提示提升的非管理员也会返回true

    【讨论】:

    • 配置数据确实需要共享,即使有多个用户。日志文件被写入一个路径在配置中的文件夹,并且路径通常会像 C:\Log 这样简单,所以虚拟化应该不是问题(但目前某些日志文件可能具有不同的权限)。我使用的是 C++,所以我使用的是 Windows SDK 而不是 .NET。这个链接看起来很有希望:goo.gl/DevVT
    • 所以你应该分区并将写入配置数据放入提升的东西。
    【解决方案2】:

    UAC 是一个相当大的变化;在事实充满危险之后,试图硬塞你的应用程序以适应它。将注册表和日志文件位置从机器区域更改为用户区域不是更容易吗?例如HKCU 和 CSIDL_APPDATA。如果这对您不起作用,那么用户只需要提升运行您的应用程序即可;你可以指定一个 requireAdministrator 清单。

    【讨论】:

    • 感谢您提供标准的 HKCU 答案,但我想在其他人的帮助下进一步探索 HKLM 路径。毕竟,其他应用程序使用它就很好。实际上,我喜欢用户必须提升才能更改配置的事实,因为这种情况并不经常发生。
    猜你喜欢
    • 2011-12-15
    • 2021-03-02
    • 2015-02-24
    • 1970-01-01
    • 2015-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多