使用英语阅读

通过


安全注意事项:Microsoft Windows Shell

本主题提供有关与 Windows Shell 相关的安全注意事项的信息。 本文档无法提供所有需要了解的安全问题,而是将其用作此特定技术领域的起点和参考。

Shell 控制系统的某些重要方面,包括一些未正确处理的潜在安全风险方面。 本主题概述了一些更常见的问题,以及如何在应用程序中解决这些问题。 请记住,安全性不限于基于 Internet 的漏洞。 在共享系统(包括可通过终端服务访问的系统)上,还必须确保用户不能执行任何可能损害共享系统的其他人的操作。

正确安装应用程序

通过正确安装应用程序,可以缓解大多数潜在的 Shell 安全问题。

  • 在 Program Files 文件夹下安装应用程序。

    操作系统 位置
    Windows XP、Windows Server 2003 及更早版本 CSIDL_PROGRAM_FILES
    Windows Vista 及更高版本 FOLDERID_ProgramFiles、FOLDERID_ProgramFilesX86、FOLDERID_ProgramFilesX64、FOLDERID_ProgramFilesCommon、FOLDERID_ProgramFilesCommonX86或FOLDERID_ProgramFilesCommonX64。 有关详细信息,请参阅 KNOWNFOLDERID

     

  • 不要将用户数据存储在 Program Files 文件夹下。

    对所有用户通用的数据使用适当的数据文件夹。

    操作系统 位置
    Windows XP、Windows Server 2003 及更早版本 CSIDL_COMMON_APPDATA
    Windows Vista 及更高版本 FOLDERID_ProgramData

     

    对属于特定用户的数据使用相应的用户数据文件夹。

    操作系统 位置
    Windows XP、Windows Server 2003 及更早版本 CSIDL_APPDATA、CSIDL_PERSONAL等。
    Windows Vista 及更高版本 FOLDERID_RoamingAppData、FOLDERID_Documents等。

     

  • 如果必须安装到 Program Files 文件夹以外的位置,请确保正确设置访问控制列表 (ACL) ,以便用户无法访问文件系统的不适当部分。 特定于特定用户的任何数据都应具有阻止任何其他用户访问数据的 ACL。

  • 设置文件关联时,请务必正确指定命令行。 使用完全限定的路径,并将包含空格的任何元素用引号括起来。 将命令参数换行到单独的引号中。 否则,可能会错误地分析字符串,并且应用程序将无法正常启动。 此处显示了两个正确格式的命令行示例。

    "C:\Program Files\MyApp\MyApp.exe" "%1" "%2"
    C:\MyAppDir\MyApp\MyApp.exe "%1"
    

备注

标准安装文件夹的位置可能因系统而异。 若要获取特定 Windows Vista 或更高版本系统上标准文件夹的位置,请使用相应的 KNOWNFOLDERID 值调用 SHGetKnownFolderPath。 在 Windows XP、Windows Server 2003 或更早的系统中,使用相应的 CSIDL 值调用 SHGetFolderLocationSHGetFolderPath

 

Shlwapi

Shell 轻型 API (Shlwapi) 包含许多字符串操作函数。 错误地使用这些函数可能会导致字符串意外截断,且不会返回截断通知。 在以下情况下,不应使用 Shlwapi 函数。 列出的替代函数(风险较少)应用于代替它们。

Shlwapi 函数 替代函数
StrCatStrNCat StringCchCatStringCbCat 和相关函数
StrCpyStrCpyN StringCchCopyStringCbCopy 和相关函数
wnsprintfwvnsprintf StringCchPrintfStringCbPrintf 和相关函数

 

对于返回文件路径的 PathRelativePathTo 等函数,始终将缓冲区的大小设置为MAX_PATH个字符。 这样做可确保缓冲区足够大,可以容纳最大的文件路径,以及终止 null 字符。

有关备用字符串函数的详细信息,请参阅 About Strsafe.h

自动完成

不要对密码使用自动完成功能。

可以使用多个 Shell 函数来启动应用程序:ShellExecuteShellExecuteEx、WinExecSHCreateProcessAsUserW。 请确保提供要执行的应用程序的明确定义。

  • 提供可执行文件的路径时,请提供完全限定的路径。 不要依赖 Shell 来查找文件。
  • 如果提供的命令行字符串包含空格,请将该字符串用引号括起来。 否则,分析程序可能会将包含空格的单个元素解释为多个元素。

移动和复制文件

系统安全的一个关键是正确分配 ACL。 还可以使用加密文件。 请确保在移动或复制文件时,为这些文件分配了正确的 ACL,并且它们未被意外解密。 这包括将文件移动到 回收站以及文件系统中。 将 IFileOperation (Windows Vista 或更高版本) 或 SHFileOperation (Windows XP 及早期) 。 请勿使用 MoveFile,这可能未设置目标文件的预期 ACL。

编写安全命名空间扩展

Shell 命名空间扩展是向用户呈现数据的一种强大而灵活的方法。 但是,如果未正确编写它们,它们可能会导致系统故障。 需要记住的一些要点:

  • 不要假定图像等数据的格式正确。
  • 不要假定MAX_PATH等效于字符串中的 字节 数。 它是 字符数。

安全警报

下表列出了一些功能,如果使用不当,可能会损害应用程序的安全性。

Feature 缓解措施
ShellExecuteShellExecuteEx 依赖于检查一系列默认位置以查找特定文件的搜索可用于欺骗攻击。 使用完全限定的路径来确保访问所需的文件。
StrCat 第一个参数 psz1 必须足够大才能容纳 psz2 和结束的“\0”,否则可能会出现缓冲区溢出。 请改用以下替代方法之一。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCatStringCchCatExStringCchCatNStringCchCatNEx
StrCatBuff 不保证最终字符串以 null 结尾。 请改用以下替代方法之一。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCatStringCchCatExStringCchCatNStringCchCatNEx
StrCatChainW 不保证最终字符串以 null 结尾。 请改用以下替代方法之一。 StringCbCatExStringCbCatNExStringCchCatExStringCchCatNEx
StrCpy 第一个参数 psz1 必须足够大才能容纳 psz2 和结束的“\0”,否则可能会出现缓冲区溢出。 请改用以下替代方法之一。 StringCbCopyStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyNStringCchCopyNEx
StrCpyN 不保证复制的字符串以 null 结尾。 请改用以下替代方法之一。 StringCbCopyStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyN、StringCchCopyNEx
StrDup StrDup 假定 lpsz 是以 null 结尾的字符串。 此外,不保证返回的字符串以 null 结尾。 请改用以下替代方法之一。 StringCbCatStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyNStringCchCopyNEx
StrNCat 第一个参数 pszFront 必须足够大,以便保存 pszBack 和结束的“\0”,否则可能会发生缓冲区溢出。 请注意,最后一个参数 cchMax 是要复制到 pszFront 中的字符数,不一定是 pszFront 的大小(以字节为单位)。 请改用以下替代方法之一。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCatStringCchCatExStringCchCatNStringCchCatNEx
wnsprintf 不保证复制的字符串以 null 结尾。 请改用以下替代方法之一。 StringCbPrintfStringCbPrintfExStringCbVPrintfStringCbVPrintfExStringCchPrintfStringCchPrintfExStringCchVPrintfStringCchVPrintfEx
wvnsprintf 不保证复制的字符串以 null 结尾。 请改用以下替代方法之一。 StringCbPrintfStringCbPrintfExStringCbVPrintfStringCbVPrintfExStringCchPrintfStringCchPrintfExStringCchVPrintfStringCchVPrintfEx

 

Microsoft 安全性

安全开发人员中心

Microsoft 解决方案加速器

安全 TechCenter

关于 Strsafe.h