Security Considerations: Microsoft Windows Shell

This topic provides information about security considerations related to the Windows Shell. This document cannot provide all you need to know about security issues—instead, use it as a starting point and reference for this specific technology area.

The Shell controls a number of important aspects of the system, including several that present potential security risks if they are not properly handled. This topic outlines some of the more common issues and how to address them in your applications. Remember that security is not limited to Internet-based exploits. On shared systems, including systems that are accessible through Terminal Services, you must also ensure that users cannot do anything that could harm others who share the system.

Installing Your Application Properly

The majority of potential Shell security issues can be mitigated by correctly installing your application.

  • Install the application under the Program Files folder.

    Operating System Location
    Windows XP, Windows Server 2003, and earlier CSIDL_PROGRAM_FILES
    Windows Vista and later FOLDERID_ProgramFiles, FOLDERID_ProgramFilesX86, FOLDERID_ProgramFilesX64, FOLDERID_ProgramFilesCommon, FOLDERID_ProgramFilesCommonX86, or FOLDERID_ProgramFilesCommonX64. See KNOWNFOLDERID for specifics.

     

  • Do not store user data under the Program Files folder.

    Use the appropriate data folder for data that is common to all users.

    Operating System Location
    Windows XP, Windows Server 2003, and earlier CSIDL_COMMON_APPDATA
    Windows Vista and later FOLDERID_ProgramData

     

    Use the appropriate user data folder for data that belongs to a particular user.

    Operating System Location
    Windows XP, Windows Server 2003, and earlier CSIDL_APPDATA, CSIDL_PERSONAL, and others.
    Windows Vista and later FOLDERID_RoamingAppData, FOLDERID_Documents, and others.

     

  • If you must install to a location other than the Program Files folder, make sure that you set access control lists (ACLs) properly so that users do not have access to inappropriate parts of the file system. Any data that is specific to a particular user should have an ACL that prevents any other user from accessing it.

  • When you set up file associations, be sure to properly specify the command line. Use a fully qualified path and wrap any elements that contain white space in quotation marks. Wrap command parameters in separate quotation marks. Otherwise, the string might be incorrectly parsed and the application will not launch properly. Two examples of properly formed command lines are shown here.

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

Note

The location of the standard installation folders might vary from system to system. To get the location of a standard folder on a particular Windows Vista or later system, call SHGetKnownFolderPath with the appropriate KNOWNFOLDERID value. In Windows XP, Windows Server 2003, or earlier systems, call SHGetFolderLocation or SHGetFolderPath with the appropriate CSIDL value.

 

Shlwapi

The Shell Lightweight API (Shlwapi) includes a number of string manipulation functions. Using these functions incorrectly can lead to unexpectedly truncated strings with no notification of the truncation being returned. In the following cases, the Shlwapi functions should not be used. The listed alternative functions, which pose fewer risks, should be used in their place.

Shlwapi Function Alternative Function
StrCat,StrNCat StringCchCat, StringCbCat and related functions
StrCpy, StrCpyN StringCchCopy, StringCbCopy and related functions
wnsprintf, wvnsprintf StringCchPrintf, StringCbPrintf and related functions

 

With functions such as PathRelativePathTo that return a file path, always set the size of the buffer to MAX_PATH characters. Doing so ensures that the buffer is large enough to hold the largest possible file path, plus a terminating null character.

For more information on the alternative string functions, see About Strsafe.h.

Autocomplete

Do not use the Autocomplete feature for passwords.

There are several Shell functions that you can use to launch applications: ShellExecute, ShellExecuteEx, WinExec, and SHCreateProcessAsUserW. Make sure you provide an unambiguous definition of the application that is to be executed.

  • When providing the executable file's path, provide the fully qualified path. Do not depend on the Shell to locate the file.
  • If you provide a command-line string that contains white space, wrap the string in quotation marks. Otherwise, the parser might interpret a single element that contains spaces as multiple elements.

Moving and Copying Files

One key to system security is properly assigning ACLs. You also might use encrypted files. Make sure that when you move or copy files, that they are assigned the correct ACL and that they have not been accidentally decrypted. This includes moving files to the Recycle Bin, as well as within the file system. Use IFileOperation (Windows Vista or later) or SHFileOperation (Windows XP and earlier). Do not use MoveFile, which might not set the expected ACL for the destination file.

Writing Secure Namespace Extensions

Shell namespace extensions are a powerful and flexible way to present data to the user. However, they can cause system failure if they are not correctly written. Some key points to keep in mind:

  • Do not assume that data such as images are formatted correctly.
  • Do not assume that MAX_PATH is equivalent to the number of bytes in a string. It is the number of characters.

Security Alerts

The following table lists some features that can, if used incorrectly, compromise the security of your applications.

Feature Mitigation
ShellExecute, ShellExecuteEx Searches that depend on checking a series of default locations to find a specific file can be used in a spoofing attack. Use a fully qualified path to ensure that you access the desired file.
StrCat The first argument, psz1, must be large enough to hold psz2 and the closing '\0', otherwise a buffer overrun might occur. Use one of the following alternatives instead. StringCbCat, StringCbCatEx, StringCbCatN, StringCbCatNEx, StringCchCat, StringCchCatEx, StringCchCatN, or StringCchCatNEx.
StrCatBuff The final string is not guaranteed to be null-terminated. Use one of the following alternatives instead. StringCbCat, StringCbCatEx, StringCbCatN, StringCbCatNEx, StringCchCat, StringCchCatEx, StringCchCatN, or StringCchCatNEx.
StrCatChainW The final string is not guaranteed to be null-terminated. Use one of the following alternatives instead. StringCbCatEx, StringCbCatNEx, StringCchCatEx, or StringCchCatNEx.
StrCpy The first argument, psz1, must be large enough to hold psz2 and the closing '\0', otherwise a buffer overrun might occur. Use one of the following alternatives instead. StringCbCopy, StringCbCopyEx, StringCbCopyN, StringCbCopyNEx, StringCchCopy, StringCchCopyEx, StringCchCopyN, or StringCchCopyNEx.
StrCpyN The copied string is not guaranteed to be null-terminated. Use one of the following alternatives instead. StringCbCopy, StringCbCopyEx, StringCbCopyN, StringCbCopyNEx, StringCchCopy, StringCchCopyEx, StringCchCopyN, StringCchCopyNEx.
StrDup StrDup assumes that lpsz is a null-terminated string. Further, the returned string is not guaranteed to be null-terminated. Use one of the following alternatives instead. StringCbCat, StringCbCopyEx, StringCbCopyN, StringCbCopyNEx, StringCchCopy, StringCchCopyEx, StringCchCopyN, or StringCchCopyNEx.
StrNCat The first argument, pszFront, must be large enough to hold pszBack and the closing '\0', otherwise a buffer overrun might occur. Be aware that the last argument, cchMax, is the number of characters to copy into pszFront, not necessarily the size of the pszFront in bytes. Use one of the following alternatives instead. StringCbCat, StringCbCatEx, StringCbCatN, StringCbCatNEx, StringCchCat, StringCchCatEx, StringCchCatN, or StringCchCatNEx.
wnsprintf The copied string is not guaranteed to be null-terminated. Use one of the following alternatives instead. StringCbPrintf, StringCbPrintfEx, StringCbVPrintf, StringCbVPrintfEx, StringCchPrintf, StringCchPrintfEx, StringCchVPrintf, or StringCchVPrintfEx.
wvnsprintf The copied string is not guaranteed to be null-terminated. Use one of the following alternatives instead. StringCbPrintf, StringCbPrintfEx, StringCbVPrintf, StringCbVPrintfEx, StringCchPrintf, StringCchPrintfEx, StringCchVPrintf, or StringCchVPrintfEx.

 

Microsoft Security

Security Developer Center

Microsoft Solution Accelerators

Security TechCenter

About Strsafe.h