安全性考慮:國際功能
本主題提供與國際支援功能相關的安全性考慮資訊。 您可以使用它作為起點,然後查看技術特定安全性考慮感興趣的國際技術檔。
本主題包含下列各節。
- 字元轉換函式的安全性考慮
- 比較函式的安全性考慮
- 檔名中字元集的安全性考慮
- 國際化功能變數名稱的安全性考慮
- ANSI 函式 安全性考慮
- Unicode 正規化 安全性考慮
字元轉換函式的安全性考慮
MultiByteToWideChar 和 WideCharToMultiByte 是最常用來在 ANSI 與 Unicode 之間轉換字元的 Unicode 和字元集函式。 這些函式有可能造成安全性風險,因為它們會以不同的方式計算輸入和輸出緩衝區的元素。 例如,MultiByteToWideChar 接受以位元組為單位計算的輸入緩衝區,並將轉換的字元放入 Unicode 字元大小的緩衝區中。 當您的應用程式使用此函式時,它必須正確調整緩衝區的大小,以避免緩衝區滿溢。
WideCharToMultiByte 預設為代碼頁的「最適合」對應,例如 1252。 不過,這種類型的對應允許相同字串的多個表示法,可能會讓您的應用程式容易受到攻擊。 例如,具有右斜體 (“Ä”) 的拉丁大寫字母 A 可能會對應至拉丁大寫字母 A (“A”):亞洲語言中的 Unicode 字元可能會對應至斜線 (“/” )。 從安全性觀點來看,最好使用 WC_NO_BEST_FIT_CHARS 旗標。
例如,某些代碼頁,例如 5022x (iso-2022-x) 代碼頁原本就不安全,因為它們允許相同字串的多個表示法。 正確撰寫的程式代碼會以 Unicode 格式執行安全性檢查,但這些類型的代碼頁會擴充應用程式的攻擊易感性,並應盡可能避免。
比較函式的安全性考慮
字串比較可能會有安全性問題。 由於所有比較函式稍有不同,因此一個函式可能會將兩個字串報告為相等,而另一個函式可能會將其視為相異。 以下是應用程式可用來比較字串的數個函式:
- lstrcmpi。 根據地區設定的規則比較兩個字元字串,而不區分大小寫。 函式會藉由檢查第一個字元彼此、彼此對第二個字元等等,以比較字串,直到找到不相等或到達字串的結尾為止。
- lstrcmp。 使用與 lstrcmpi 類似的技術比較字串。 唯一的差異在於 lstrcmp 執行區分大小寫的字串比較。
- CompareStringCompareStringEx (Windows Vista 和更新版本)。 在應用程式提供的地區設定上執行字串比較。 CompareStringEx 類似於 CompareString,但它會 地區設定名稱 來識別地區設定,而不是 地區設定標識符。 這些函式類似於 lstrcmpi 和 lstrcmp,不同之處在於它們會在特定地區設定上運作,而不是用戶選取的地區設定。
- CompareStringOrdinal (Windows Vista 和更新版本)。 比較兩個 Unicode 字串,以測試二進位等價。 除了不區分大小寫的選項之外,此函式會忽略所有非二進位等價,並測試所有程式代碼點是否相等,包括語言 排序 配置中未給予任何權數的程式代碼點。 請注意,本主題中提及的其他比較函式不會測試所有程式代碼點是否相等。
- FindNLSStringFindNLSStringEx (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 Yen 符號 (U+00A5) 對應至同一個字元。 基於安全性考慮,您的應用程式通常不允許 Unicode 字串中的字元 U+00A5,而 Unicode 字串可能會轉換為 FAT 檔名。
國際化域名的安全性考慮
國際化功能變數名稱是由網路工作組 RFC 3490 所指定:將應用程式 (IDNA) 中的功能變數名稱國際化。 此標準引進許多安全性問題。
代表不同腳本中特定字元的字元可能會類似或甚至相同。 例如,在許多字型中,斯拉夫小寫 A (“a”) 與拉丁小寫 A (“a”) 不區分。 無法以視覺方式告訴「example.com」和「example.com」是兩個不同的功能變數名稱,一個名稱中有拉丁小寫 A,另一個則使用斯拉夫小寫 A。無良主機網站可以使用這個視覺模棱兩可的模棱兩可來假裝是詐騙攻擊中的另一個網站。
IDNA 允許IDN的擴充字元集也在特定腳本中具有詐騙潛力。 例如, 連字元減號(“-” U+002D)、連字元(“—” U+2010)、非中斷連字元(“-” U+2 之間有很強的相似性011、數位破折號 (“\u2012” U+2012)、虛線 (“–” U+2013) 和減號 (“{” U+2212)。
某些相容性組合也出現了類似的問題。 例如,單一 Unicode 字元 NUMBER20 FULL STOP (“20.”, U+249B) 會轉換成 “20”。(U+0032 U+0030 U+002E) 在 NamePrep 步驟中,在轉換成 Punycode 之前。 換句話說,這個組合會插入句點(完整停止)。 這類組合具有詐騙潛力。
在IDN中混合不同的腳本不一定表示詐騙或欺騙意圖。 技術報告 #36:Unicode 安全性考慮 提供數個包含混合腳本的合理 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+006 的變更 3 U+001A U+003C U+0077 U+0069 U+006E U+0064 U+006F U+0077 U+0073 (c:\windows)
格式為 KC 正規化。 如果應用程式在實作正規化之前測試冒號和反斜杠字元是否存在,則結果可能是無意的檔案存取。
雖然 Unicode 正規化是讓作系統安全化的元素,但請記住,正規化不是完整安全策略的替代專案。
相關主題
-
函式原型 的 慣例