安全性考慮:Windows 用戶介面

本主題提供 Windows 使用者介面中安全性考慮的相關信息。 本主題不會提供您對於安全性問題所需的所有知識。 請改用它作為此技術領域的起點和參考。

隨著計算機互連能力的增加,開發人員現在必須關注應用程式安全性。 不過,安全性也會增強一般應用程式安全性和強固性;因此,開發人員可以提供良好的用戶體驗是另一種方式。 下列主題討論使用 Windows 使用者介面時的一些潛在安全性考慮。

字串考慮

許多函式、訊息和宏在其參數中使用字串。 不過,通常不會檢查字串是否有 Null 終止或長度。 相關的考慮是錯誤計算字串或緩衝區的長度。 在任一情況下,這可能會導致緩衝區溢位或數據截斷,這可能會影響您的應用程式。 如需緩衝區滿溢和其他安全性考慮的詳細資訊,請參閱 2002 年 Microsoft Press 的 Michael Howard 和 David Leblanc 撰寫安全程式代碼

若要以安全的方式處理字串,您應該執行下列動作:

  • 視需要檢查字串是否有 Null 終止或適當的長度。
  • 特別小心判斷字串或緩衝區的長度,特別是當它包含 TCHAR 值時。
  • 如果您建立字串或使用先前使用的字串,請視需要將其初始化為零或插入 Null 終止符。

此外,請考慮在處理字串時使用 Str 保管庫 函式。 這些函式是設計來安全地處理字串。

使用者輸入

Windows 使用者介面與從使用者取得和回應信息有關。 不過,輸入不正確數據的使用者可能會中斷您的應用程式,無論他們是否打算這麼做。 因此,基數規則是必須驗證所有輸入。

主要考慮事項是字串數據,如字串考慮中所述。 不過,在您的應用程式使用之前,應該先驗證所有類型的輸入。 另一個考慮是當數據在某個時間點進行驗證,但在使用數據之前變更,例如,接收提供文字長度的訊息時。 因此,如果數據有可能變更,您應該先檢查數據,再使用它

安全性警示

下表列出不正確地使用的功能可能會危害應用程式的安全性。

功能 風險降低
GetAtomName 指定緩衝區的大小時請小心。
GlobalGetAtomName 任何應用程式都可以存取全域字串 Atom。 不過,如果另一個應用程式不小心,可能會錯誤地處理其參考計數並加以刪除。 您應該考慮改用全域整數原子。
ImpersonateDdeClientWindow 如果函式失敗,則會在呼叫進程的安全性內容中提出後續用戶端要求。 如果呼叫進程是以高許可權帳戶執行,就可能會發生問題。 因此,如果呼叫失敗或引發錯誤,則不會繼續執行用戶端要求。
DdeImpersonateClient 如果函式失敗,則會在呼叫進程的安全性內容中提出後續用戶端要求。 如果呼叫進程是以高許可權帳戶執行,就可能會發生問題。 因此,如果呼叫失敗或引發錯誤,則不會繼續執行用戶端要求。
GetClipboardFormatName 錯誤計算 lpszFormatName 緩衝區的適當大小,特別是當應用程式同時用於 ANSI 和 Unicode 版本時,可能會導致緩衝區溢位。 此外,請注意,如果字串超過 cchMaxCount 參數,則會截斷字串,這可能會導致資訊遺失。
GetMenuString lpString 參數是 TCHAR 緩衝區,而 nMaxCount 是 TCHARs 中的功能表字串長度。 正確調整這些參數的大小可以是字元的功能表字串長度。 調整這些參數的大小不正確可能會導致字串截斷,導致數據可能遺失。
GetStringTypeAGetStringTypeExGetStringTypeW 若要避免緩衝區溢位,請正確設定 lpCharType 緩衝區的大小
LoadLibrary 不正確地使用 LoadLibrary 可能會藉由載入錯誤的 DLL 來危害應用程式的安全性。
LoadString 不正確的使用包括指定 nBufferMax 參數中的錯誤大小。 例如,sizeof(lpBuffer) 會以位元組為單位提供緩衝區的大小,這可能會導致函式 Unicode 版本的緩衝區溢位。 緩衝區溢位情況是應用程式中許多安全性問題的原因。 在此情況下,using sizeof(lpBuffer)/sizeof(TCHAR) 會提供適當的緩衝區大小。
lstrcat 此函式會使用結構化例外狀況處理 (SEH) 來攔截存取違規和其他錯誤。 當此函式攔截 SEH 錯誤時,它會傳回 NULL,而不會以 Null 終止字串,而不終止字串,而不會通知呼叫端錯誤。 呼叫端無法放心地假設空間不足是錯誤狀況。 第一個自變數 lpString1 必須夠大,才能保存 lpString2 和結尾 '\0',否則可能會發生緩衝區滿溢。 如果發生存取違規,緩衝區滿溢可能會導致對應用程式的阻斷服務攻擊。 在最壞的情況下,緩衝區滿溢可能會讓攻擊者將可執行的程式代碼插入您的進程,特別是如果 lpString1 是堆棧型緩衝區。 請考慮使用下列其中一個替代方案。 StringCbCatStringCchCat
lstrcpy 此函式會使用結構化例外狀況處理 (SEH) 來攔截存取違規和其他錯誤。 當此函式攔截 SEH 錯誤時,它會傳回 NULL,而不會以 Null 終止字串,而不終止字串,而不會通知呼叫端錯誤。 呼叫端無法放心地假設空間不足是錯誤狀況。 第一個自變數 lpString1 必須夠大,才能保存 lpString2 和結尾 '\0',否則可能會發生緩衝區滿溢。 如果發生存取違規,緩衝區滿溢可能會導致對應用程式的阻斷服務攻擊。 在最壞的情況下,緩衝區滿溢可能會讓攻擊者將可執行的程式代碼插入您的進程,特別是如果 lpString1 是堆棧型緩衝區。 請考慮改用 StringCchCopy
lstrcpyn 此函式會使用結構化例外狀況處理 (SEH) 來攔截存取違規和其他錯誤。 當此函式攔截 SEH 錯誤時,它會傳回 NULL,而不會以 Null 終止字串,而不終止字串,而不會通知呼叫端錯誤。 呼叫端無法放心地假設空間不足是錯誤狀況。 如果 lpString1 不夠大,無法包含複製的字串,可能會發生緩衝區滿溢。 此外,複製整個字串時,請注意 sizeof 會傳回位元組數目,而不是 WCHAR該 sizeof 會傳回位元組數目,而不是字元,此函式的 Unicode 版本不正確。 如果發生存取違規,緩衝區滿溢可能會對應用程式造成拒絕服務攻擊。 在最壞的情況下,緩衝區滿溢可能會讓攻擊者將可執行的程式代碼插入您的進程,特別是如果 lpString1 是堆棧型緩衝區。 請考慮改用 StringCchCopy
lstrlen lstrlen 假設 lpString 是 Null 終止的字串。 如果不是,這可能會導致緩衝區滿溢或拒絕對您的應用程式的服務攻擊。 請考慮使用下列其中一個替代方案。 StringCbLengthStringCchLength
wsprintf 在 lpOut傳回的字串不保證為 Null 終止。 此外,請避免 %s 格式,這可能會導致緩衝區滿溢。 如果發生存取違規,就會對您的應用程式造成拒絕服務。 在更糟的情況下,攻擊者可以插入可執行的程序代碼。 請考慮使用下列其中一個替代方案。 StringCbPrintf、StringCbPrintfExStringCbVPrintf、StringCbVPrintfEx、StringCchPrintfStringCchPrintfExStringCchVPrintf 或 StringCchVPrintfEx。
wvsprintf 在 lpOutput傳回的字串不保證為 Null 終止。 此外,請避免使用 %s 格式,這可能會導致緩衝區溢出。 這可能會導致拒絕服務,如果導致存取違規,或攻擊者可能會插入可執行的程序代碼。 請考慮使用下列其中一個替代方案。 StringCbPrintf、StringCbPrintfExStringCbVPrintf、StringCbVPrintfEx、StringCchPrintfStringCchPrintfExStringCchVPrintf 或 StringCchVPrintfEx。

 

Microsoft 安全性

安全性和身分識別

安全性作法索引

Microsoft 安全性回應中心

安全性 API 的最佳做法