安全性考慮:國際功能

本主題提供與國際支援功能相關的安全性考慮相關資訊。 您可以使用它作為起點,然後查看技術特定安全性考慮相關國際技術的檔。

本主題包含下列各節。

字元轉換函式的安全性考慮

MultiByteToWideCharWideCharToMultiByte 是 Unicode 和字元集函式,最常用來轉換 ANSI 與 Unicode 之間的字元。 這些函式可能會造成安全性風險,因為它們會以不同的方式計算輸入和輸出緩衝區的元素。 例如, MultiByteToWideChar 會採用以位元組為單位計算的輸入緩衝區,並將轉換後的字元放入以 Unicode 字元為單位的緩衝區。 當您的應用程式使用此函式時,它必須正確調整緩衝區的大小,以避免緩衝區滿溢。

WideCharToMultiByte 預設為字碼頁「最適合」對應,例如 1252。 不過,這種類型的對應允許相同字串的多個標記法,可能會讓您的應用程式容易受到攻擊。 例如,拉丁大寫字母 A (「Ä」) 可能會對應至拉丁大寫字母 A (「A」A「) ;亞洲語言的 Unicode 字元可能會對應至斜線 (「/」) 。 WC_NO_BEST_FIT_CHARS旗標的使用,最好從安全性觀點來看。

例如,某些字碼頁,例如,5022x (iso-2022-x) 字碼頁原本就不安全,因為它們允許相同字串的多個標記法。 正確撰寫的程式碼會以 Unicode 形式執行安全性檢查,但這些類型的字碼頁會擴充應用程式的攻擊弱點,並盡可能避免。

比較函式的安全性考慮

字串比較可能會造成安全性問題。 因為所有比較函式都稍有不同,所以一個函式可能會將兩個字串回報為相等,而另一個函式可能會將它們視為相異。 以下是您的應用程式可用來比較字串的數個函式:

  • lstrcmpi。 根據地區設定的規則比較兩個字元字串,而不區分大小寫。 函式會藉由檢查第一個字元彼此比較、第二個字元彼此比較,依此類說,直到找到不相等或到達字串的結尾為止。
  • lstrcmp。 使用類似 lstrcmpi的技術比較字串。 唯一的差別在於 lstrcmp 會執行區分大小寫的字串比較。
  • CompareStringCompareStringEx (Windows Vista 和更新版本) 。 在應用程式提供的地區設定上執行字串比較。 CompareStringEx 類似于 CompareString,但它會依 地區設定名稱 來識別地區設定,而不是 地區設定識別碼。 這些函式類似于 lstrcmpilstrcmp ,不同之處在于它們在特定地區設定上運作,而不是使用者選取的地區設定。
  • CompareStringOrdinal (Windows Vista 和更新版本) 。 比較兩個 Unicode 字串,以測試二進位等價。 除了不區分大小寫的選項之外,此函式會忽略所有非二進位等價,並測試所有程式碼點是否相等,包括語言 排序 配置中未指定任何權數的代碼點。 請注意,本主題所述的其他比較函式不會測試所有程式碼點是否相等。
  • FindNLSStringFindNLSStringEx (Windows Vista 和更新版本) 。 在另一個 Unicode 字串中找出 Unicode 字串。 FindNLSStringEx 類似于 FindNLSString,不同之處在于它會依地區設定名稱來識別地區設定,而不是地區設定識別碼。
  • FindStringOrdinal (Windows 7 和更新版本) 。 在另一個 Unicode 字串中找出一個 Unicode 字串。 應用程式應該使用此函式,而不是 FindNLSString 來進行所有非語言比較。

如同 lstrcmpilstrcmpCompareString 會依字元評估字串字元。 不過,許多語言都有多個字元元素,例如,傳統西班牙文中的雙字元元素 「CH」。 由於 CompareString 會使用應用程式所提供的地區設定來識別多字元元素,而 lstrcmpilstrcmp 會使用執行緒地區設定,因此相同的字串可能不會比較為相等。

CompareString 會忽略未定義的字元,因此會傳回零 (表示許多相異字串組的相等字串) 。 字串可能包含的值,這些值不會對應至任何字元,或可能包含在應用程式定義域外具有語意的字元,例如 URL 中的控制字元。 使用此函式的應用程式應該提供錯誤處理常式和測試字串,以確保它們在使用之前有效。

注意

針對 Windows Vista 和更新版本, CompareStringEx 類似于 CompareString。 這些函式的安全性問題完全相同。

 

類似的安全性問題適用于進行隱含比較的函式,例如 FindNLSString。 根據所設定的旗標,呼叫 FindNLSString 來搜尋另一個字串的結果可能會有很大的差異。

注意

針對 Windows Vista 和更新版本, FindNLSStringEx 類似于 FindNLSString。 這些函式的安全性問題完全相同。

 

檔案名中字元集的安全性考慮

在日文語言系統上使用的 Windows 字碼頁和 OEM 字元集包含 [ (] 符號 \) ,而不是反斜線 (\) 。 因此,NTFS 和 FAT 檔案系統是禁止的字元。 將 Unicode 對應至日文語言字碼頁時,轉換函式會將反斜線 (U+005C) 和一般 Unicode 分行符號號 (U+00A5) 對應至這個相同的字元。 基於安全性考慮,您的應用程式通常不允許 Unicode 字串中的字元 U+00A5,而該字串可能會轉換成 FAT 檔案名。

國際化功能變數名稱的安全性考慮

) 網路工作組 RFC 3490 指定國際化功能變數名稱 (IDN:將應用程式中的功能變數名稱國際化 (IDNA) 。 標準引進了一些安全性問題。

代表不同腳本中特定字元的字元,看起來可能類似或甚至相同。 例如,在許多字型中,斯拉夫小寫 A (「a」a「) 無法從拉丁小寫 A (」a「) 區分。 無法以視覺化方式告訴「example.com」和「example.com」是兩個不同的功能變數名稱,一個是名稱中有拉丁小寫 A,另一個則是小寫字母 A。不突然的主機網站可以使用此視覺模棱兩可的方式,在詐騙攻擊中假設為另一個網站。

IDNA 允許 IDN 的擴充字元集也會在特定腳本中具有詐騙的可能性。 例如,連字號減號 (「-」 U+002D) 之間有強式相等,連字號 (「—」 U+2010) 非中斷連字號 (「-」 U+2011) 、圖虛線 (「\u2012」 U+2012) 、虛線 (「–」 U+2013) ,以及減號 (「-」 U+2212) 。

來自某些相容性組合的類似問題。 例如,單一 Unicode 字元 NUMBER TWENTY FULL STOP (「20.」, U+249B) 會轉換成 「20.」 (U+0032 U+0032 U+0030 U+002E) ,再轉換為 Punycode。 換句話說,這個組合會在完整停止 (插入句點) 。 這類組合有詐騙的可能性。

在 IDN 中混合不同的腳本不一定表示詐騙或詐騙意圖。 技術報告 #36:Unicode 安全性考慮 提供數個合理 IDN 範例,其中包含混合腳本的 IDN,例如 XML-Документы.com (「Документы」 是俄文的「documents」) 。

詐騙攻擊不限於 IDN。 例如,「rnicrosoft.com」 看起來很像 「microsoft.com」,但它是 ASCII 名稱。 此外,詐騙攻擊可由名稱損毀所組成。 在已知的品牌名稱後面新增額外的標籤,或在標示為安全 URL 的路徑中包含品牌名稱,無論使用 IDN 為何,都可能會混淆新手使用者。 對於某些地區設定,需要 IDN,而且無法接受這些名稱的 Punycode 格式,因為它會使名稱看起來像 gibberish。

如需此處提及之安全性問題的詳細資訊,以及與 IDNA 相關的大量其他問題,請參閱 技術報告 #36:Unicode 安全性考慮。 除了 IDNA 相關安全性問題的詳細討論之外,此報告也提供在應用程式中處理可疑 IDN 的建議。

ANSI 函式的安全性考慮

注意

建議您盡可能在全域應用程式中使用 Unicode,特別是新的 Unicode。 只有在您有覆寫不使用 Unicode 的原因時,才應該使用 ANSI 函式,例如,符合不支援 Unicode 的較舊通訊協定。

 

許多國家語言支援 (NLS) 函式,例如 GetLocaleInfoGetCalendarInfo,分別具有特定的 ANSI 版本,在此案例中為 GetLocaleInfoAGetCalendarInfoA。 當您的應用程式搭配 Unicode 型作業系統使用函式的 ANSI 版本時,例如 Windows NT、Windows 2000、Windows XP 或 Windows Vista,函式可能會失敗或產生未定義的結果。 如果您有使用 ANSI 函式與這類作業系統的吸引人的理由,請確定應用程式所傳遞的資料對 ANSI 有效。

Unicode 正規化的安全性考慮

由於 Unicode 正規化可以變更字串的形式,因此通常應該在正規化之後實作安全性機制或字元驗證演算法。 例如,假設應用程式具有可接受檔案名但不接受路徑名稱的 Web 介面。 全形 U+FF43 U+FF1A U+FF3C U+FF57 U+FF49 U+FF4E U+FF44 U+FF4F U+FF57 U+FF53 (c : \ w i n d o w s) 變更為 U+0063 U+001A U+003C U+0077 U+0069 U+006E U+0064 U+006F U+0077 U+0073 (c:\windows) 格式 KC 正規化。 如果應用程式在實作正規化之前測試冒號和反斜線字元是否存在,結果可能是非預期的檔案存取。

雖然 Unicode 正規化是讓作業系統安全的專案,但請記住正規化不是完整安全性原則的取代專案。

檔案名中使用的字元集

函數原型的慣例

處理應用程式中的排序

處理國際化功能變數名稱 (IDN)

Unicode