安全性考慮: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 中的功能表字串長度。 正確調整這些參數的大小可以是字元的功能表字串長度。 調整這些參數的大小不正確可能會導致字串截斷,導致數據可能遺失。 |
GetStringTypeA、 GetStringTypeEx、 GetStringTypeW | 若要避免緩衝區溢位,請正確設定 lpCharType 緩衝區的大小。 |
LoadLibrary | 不正確地使用 LoadLibrary 可能會藉由載入錯誤的 DLL 來危害應用程式的安全性。 |
LoadString | 不正確的使用包括指定 nBufferMax 參數中的錯誤大小。 例如,sizeof(lpBuffer) 會以位元組為單位提供緩衝區的大小,這可能會導致函式 Unicode 版本的緩衝區溢位。 緩衝區溢位情況是應用程式中許多安全性問題的原因。 在此情況下,using sizeof(lpBuffer)/sizeof(TCHAR) 會提供適當的緩衝區大小。 |
lstrcat | 此函式會使用結構化例外狀況處理 (SEH) 來攔截存取違規和其他錯誤。 當此函式攔截 SEH 錯誤時,它會傳回 NULL,而不會以 Null 終止字串,而不終止字串,而不會通知呼叫端錯誤。 呼叫端無法放心地假設空間不足是錯誤狀況。 第一個自變數 lpString1 必須夠大,才能保存 lpString2 和結尾 '\0',否則可能會發生緩衝區滿溢。 如果發生存取違規,緩衝區滿溢可能會導致對應用程式的阻斷服務攻擊。 在最壞的情況下,緩衝區滿溢可能會讓攻擊者將可執行的程式代碼插入您的進程,特別是如果 lpString1 是堆棧型緩衝區。 請考慮使用下列其中一個替代方案。 StringCbCat 或 StringCchCat。 |
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 終止的字串。 如果不是,這可能會導致緩衝區滿溢或拒絕對您的應用程式的服務攻擊。 請考慮使用下列其中一個替代方案。 StringCbLength 或 StringCchLength。 |
wsprintf | 在 lpOut 中傳回的字串不保證為 Null 終止。 此外,請避免 %s 格式,這可能會導致緩衝區滿溢。 如果發生存取違規,就會對您的應用程式造成拒絕服務。 在更糟的情況下,攻擊者可以插入可執行的程序代碼。 請考慮使用下列其中一個替代方案。 StringCbPrintf、StringCbPrintfEx、StringCbVPrintf、StringCbVPrintfEx、StringCchPrintf、StringCchPrintfEx、StringCchVPrintf 或 StringCchVPrintfEx。 |
wvsprintf | 在 lpOutput 中傳回的字串不保證為 Null 終止。 此外,請避免使用 %s 格式,這可能會導致緩衝區溢出。 這可能會導致拒絕服務,如果導致存取違規,或攻擊者可能會插入可執行的程序代碼。 請考慮使用下列其中一個替代方案。 StringCbPrintf、StringCbPrintfEx、StringCbVPrintf、StringCbVPrintfEx、StringCchPrintf、StringCchPrintfEx、StringCchVPrintf 或 StringCchVPrintfEx。 |
相關主題