安全性考慮:Microsoft Windows Shell

本主題提供與 Windows 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值呼叫SHGetFolderLocation 或 SHGetFolderPath

 

Shlwapi

Shell 輕量型 API (Shlwapi) 包含數個字串操作函式。 使用這些函式不正確地會導致意外截斷字串,且不會傳回截斷的通知。 在下列情況下,不應該使用 Shlwapi 函式。 列出的替代函式應該在其位置使用風險較少。

Shlwapi 函式 替代函式
StrCatStrNCat StringCchCatStringCbCat 和相關函式
StrCpyStrCpyN StringCchCopyStringCbCopy 和相關函式
wnsprintfwvnsprintf StringCchPrintfStringCbPrintf 和相關函式

 

使用 PathRelativePathTo 等傳回檔案路徑的函式,一律將緩衝區的大小設定為MAX_PATH個字元。 這樣做可確保緩衝區夠大,足以保存最大的可能檔案路徑,加上終止的 Null 字元。

如需替代字串函式的詳細資訊,請參閱 關於 Strsafe.h

自動完成

請勿將自動完成功能用於密碼。

有數個 Shell 函式可用來啟動應用程式: ShellExecuteShellExecuteExWinExecSHCreateProcessAsUserW。 請確定您提供要執行之應用程式的明確定義。

  • 提供可執行檔的路徑時,請提供完整路徑。 請勿相依于殼層來尋找檔案。
  • 如果您提供包含空白字元的命令列字串,請以引號括住字串。 否則,剖析器可能會將包含空格的單一元素解譯為多個元素。

移動和複製檔案

系統安全性的其中一個金鑰是正確指派 ACL。 您也可以使用加密的檔案。 請確定當您移動或複製檔案時,系統會指派正確的 ACL,而且它們未意外解密。 這包括將檔案移至 回收站,以及檔案系統內。 使用 IFileOperation (Windows Vista 或更新版本) 或 SHFileOperation (Windows XP 和舊版) 。 請勿使用 MoveFile,這可能不會設定目的地檔案的預期 ACL。

撰寫安全命名空間延伸模組

殼層命名空間延伸模組是向使用者呈現資料的強大彈性方式。 不過,如果系統未正確寫入,它們可能會造成系統失敗。 請記住一些重點:

  • 請勿假設影像之類的資料已正確格式化。
  • 請勿假設MAX_PATH相當於字串中的 位元組 數目。 這是 字元數。

安全性警示

下表列出某些功能,如果不正確使用,就會危害應用程式的安全性。

功能 降低
ShellExecuteShellExecuteExecuteEx 根據檢查一系列預設位置來尋找特定檔案的搜尋,可用於詐騙攻擊。 使用完整路徑,以確保您可以存取所需的檔案。
StrCat 第一個引數 psz1必須夠大,才能保存 psz2 和結尾 '\0',否則可能會發生緩衝區滿溢。 請改用下列其中一個替代方案。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCat、StringCchCatExStringCchCatN 或 StringCchCatNEx
StrCatBuff 最終字串不保證為 Null 終止。 請改用下列其中一個替代方案。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCat、StringCchCatExStringCchCatN 或 StringCchCatNEx
StrCatChainW 最終字串不保證為 Null 終止。 請改用下列其中一個替代方案。 StringCbCatExStringCbCatNExStringCchCatExStringCchCatNEx
StrCpy 第一個引數 psz1必須夠大,才能保存 psz2 和結尾 '\0',否則可能會發生緩衝區滿溢。 請改用下列其中一個替代方案。 StringCbCopyStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyNStringCchCopyNEx
StrCpyN 複製的字串不保證為 Null 終止。 請改用下列其中一個替代方案。 StringCbCopyStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyNStringCchCopyNEx
StrDup StrDup 假設 lpsz 是 Null 終止的字串。 此外,傳回的字串不保證為 Null 終止。 請改用下列其中一個替代方案。 StringCbCatStringCbCopyExStringCbCopyNStringCbCopyNExStringCchCopyStringCchCopyExStringCchCopyN 或 StringCchCopyNEx
StrNCat 第一個引數 pszFront必須夠大,才能保存 pszBack 和結尾 '\0',否則可能會發生緩衝區滿溢。 請注意,最後一個引數 cchMax是要複製到 pszFront的字元數,不一定 是 pszFront 的大小,以位元組為單位。 請改用下列其中一個替代方案。 StringCbCatStringCbCatExStringCbCatNStringCbCatNExStringCchCat、StringCchCatExStringCchCatN 或 StringCchCatNEx
wnsprintf 複製的字串不保證為 Null 終止。 請改用下列其中一個替代方案。 StringCbPrintfStringCbPrintfExStringCbVPrintfStringCbVPrintfExStringCchPrintfStringCchPrintfExStringCchVPrintfStringCchVPrintfEx
wvnsprintf 複製的字串不保證為 Null 終止。 請改用下列其中一個替代方案。 StringCbPrintfStringCbPrintfExStringCbVPrintfStringCbVPrintfExStringCchPrintfStringCchPrintfExStringCchVPrintfStringCchVPrintfEx

 

Microsoft 安全性

資訊安全開發人員中心

Microsoft Solution Accelerator

資訊安全技術中心

關於 Strsafe.h