安全性考慮:國際功能
本主題提供與國際支援功能相關的安全性考慮相關資訊。 您可以使用它作為起點,然後查看技術特定安全性考慮相關國際技術的檔。
本主題包含下列各節。
字元轉換函式的安全性考慮
MultiByteToWideChar 和 WideCharToMultiByte 是 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 會執行區分大小寫的字串比較。
- CompareString、CompareStringEx (Windows Vista 和更新版本) 。 在應用程式提供的地區設定上執行字串比較。 CompareStringEx 類似于 CompareString,但它會依 地區設定名稱 來識別地區設定,而不是 地區設定識別碼。 這些函式類似于 lstrcmpi 和 lstrcmp ,不同之處在于它們在特定地區設定上運作,而不是使用者選取的地區設定。
- CompareStringOrdinal (Windows Vista 和更新版本) 。 比較兩個 Unicode 字串,以測試二進位等價。 除了不區分大小寫的選項之外,此函式會忽略所有非二進位等價,並測試所有程式碼點是否相等,包括語言 排序 配置中未指定任何權數的代碼點。 請注意,本主題所述的其他比較函式不會測試所有程式碼點是否相等。
- FindNLSString、FindNLSStringEx (Windows Vista 和更新版本) 。 在另一個 Unicode 字串中找出 Unicode 字串。 FindNLSStringEx 類似于 FindNLSString,不同之處在于它會依地區設定名稱來識別地區設定,而不是地區設定識別碼。
- FindStringOrdinal (Windows 7 和更新版本) 。 在另一個 Unicode 字串中找出一個 Unicode 字串。 應用程式應該使用此函式,而不是 FindNLSString 來進行所有非語言比較。
如同 lstrcmpi 和 lstrcmp, CompareString 會依字元評估字串字元。 不過,許多語言都有多個字元元素,例如,傳統西班牙文中的雙字元元素 「CH」。 由於 CompareString 會使用應用程式所提供的地區設定來識別多字元元素,而 lstrcmpi 和 lstrcmp 會使用執行緒地區設定,因此相同的字串可能不會比較為相等。
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) 函式,例如 GetLocaleInfo 和 GetCalendarInfo,分別具有特定的 ANSI 版本,在此案例中為 GetLocaleInfoA 和 GetCalendarInfoA。 當您的應用程式使用 ANSI 版本的函式搭配 Unicode 型作業系統時,例如 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 正規化是讓作業系統安全的專案,但請記住正規化不是完整安全性原則的取代專案。
相關主題