修复 Windows(或您自己的应用程序,如果适用 - 在您的示例中,您需要修复 Windows)。TOCTOU 漏洞只能通过不将检查与使用分开来解决。我见过的应用程序中一个更常见的例子:临时文件(是的,人们仍然会弄错这个)。一个文件在你看时不存在并不意味着当你去使用它时它也不存在。
具体到这个例子:Mac OS X 的授权服务不会在你登录的时候检查你有什么权限,它会在获取时判断你是否可以获取权限。在设计良好的应用程序中,特权组件会在使用时检查您是否有权限,因此 TOCTOU 漏洞的窗口是有限的。它不为零——我可以获得一项权利,撤销该权利,然后将我已经获得的安全上下文传递给特权组件,但有时间限制。
因此,假设您设法在 Microsoft 找到了一份工作,并且您的任务是修复此错误。您会发现(我正在编写 API 以进行论证,但这就是它的工作方式)当用户登录时,会话管理器会securityContext = GetUserAccountControlsContext();
从中央数据库或目录服务复制用户的权限,以便会话可以参考它。
稍后,您会发现管理用户权限调用的代码IsUserAuthorizedForAction(kMakeUserAdminAction, securityContext);
以发现是否应启用使自己成为管理员的 UI。当他单击按钮时,MakeUserAdmin(user)
也调用相同的检查,具有相同的安全上下文。
修复是删除上下文的初始获取。将测试更改为IsUserAuthorizedForAction(action, context)
调用GetUserAccountControlsContext()
自己。结果不应被缓存,而应在每次调用时重新查找。这留下了两个突出的问题:
- 当 UI 启用检查完成时,用户没有被授权,但在稍后的某个时间变得如此。您可以通过观察安全上下文的更改来解决此问题,或者将其视为不常发生的轻微烦恼。
- 当 UI 启用检查完成时,用户被授权,但当他点击按钮时,他没有被授权。
MakeUserAdmin()
这是通过测试(最新的)安全上下文的事实来处理的。如果它实际上无法获得足够的权限来做它需要的事情,它应该抛出一个异常。