解决两个难懂的安全性问题
2009-03-09 20:02:25 来源:WEB开发网发现缺陷
没有人看出上星期的代码中的错误,但很多人已接近目标。其中的问题是为明文和密文使用了相同的缓冲区。您永远都不能这样做。
乍看起来,使用相同的缓冲区存储明文,然后加密明文产生的密文似乎很好。在大多数情况下也是这样。但在多线程环境中就不是这样了。设想一下,您的代码中出现了一个“竞争状态”,而您却并不知道。(竞争状态是由对软件中的事件的相对时间产生意外的严格依赖而引起的。它们通常与同步错误一起出现。)坦白地说,您永远不会知道存在着严重的竞争状态,等知道时已经太晚了。请再考虑一下,您的应用程序的正常流程如下所示:
使用明文加载缓冲区。
加密缓冲区。
将缓冲区内容发送给接收者。
这看起来很正常。但是,设想您有一个多线程应用程序,由于某种原因,最后两个步骤由于竞争状态而被交换:
使用明文加载缓冲区。
将缓冲区环境发送给接收者。
加密缓冲区。
接收者只接收到一些明文!这是在 Internet Information Server 4.0 中修复的一个错误。在非常特殊的负载和极少数情况下,当使用安全套接字层 (SSL) 保护从服务器至用户的数据通道时,服务器可能会遵循此模式,并将一个未加密的数据信息包发送给用户。这种潜在问题的破坏很小;只向用户(或者可能是一个攻击者)发送了一个信息包。并且当用户接收到信息包时,客户端软件将断开连接。据说该问题已被 Microsoft 修复了。有关该缺陷的详细信息,请访问 http://www.microsoft.com/technet/treeview/default.asp?url=/technet/security/bulletin/ms99-053.asp(英文)。
修复的方法是使用两个缓冲区。一个缓冲区用于明文,另一个用于密文,并确保密文在执行不同调用时已被清空。
您能指出此代码中的错误吗?
void ShuffleAndUpdate(char *szName, char *szPwd,
DWORD index,
DWORD d) {
DWORD dwArray[32];
ZeroMemory(dwArray,sizeof(dwArray));
BOOL fAllowAccess = FALSE;
if (IsValidUser(szName,szPwd)) {
fAllowAccess = TRUE;
ShuffleArray(dwArray,szName);
}
dwArray[index]= d;
if (fAllowAccess) {
// 执行某些敏感的操作
}
}
Michael Howard 是 Microsoft 的 Secure Windows Initiative 组的安全程序经理,是 Writing Secure Code 的作者之一,也是 Designing Secure Web-based for Applications for Windows 2000 的主要作者。他的主要工作就是确保人们设计、构建、测试和记录无缺陷的安全系统。他最喜欢的话是“尺有所短,寸有所长”。
更多精彩
赞助商链接