關于 Unicode 每個程序員應該知道的 5 件事
上周末,曝出了山寨WhatsApp Android應用程序的新聞,看似由相同的開發者提供作為了官方應用程序。欺詐分子通過在開發者名字中包含unicode非輸出空格來避免驗證。在Play store的維護人員注意到之前,黑客已經欺騙了一百多萬人。
Unicode是一個令人難以置信的有用標準,它能使全世界的計算機、智能手機和智能手表以同樣的方式顯示相同的信息。不幸的是,它的復雜性使它成為了欺詐分子和惡作劇的金礦。如果谷歌這樣的巨頭都無法抵御由Unicode引起的基本問題,那么對于小公司來說,這或許就是一場看起來注定失敗的戰斗。但是,這些問題大都圍繞一些漏洞出現。以下是所有開發人員需要了解的關于Unicode以防止欺詐的最重要的5件事情。
1、許多Unicode點不可見
Unicode有若干零寬度的代碼點,例如零寬度連接器(U+200D)和零寬度非連接器(U+200C),這些用連字符號連接的工具都是暗示的(hints)。它們對屏幕外觀沒有可見的影響,但是它們會影響字符串比較,這就是為什么山寨WhatApp能夠躲過漏檢這么久的原因。這些字符大多數都在常規的標點符號塊(從U+2000到U+206F)。一般來說,沒有理由允許任何人在標識符中使用此標點符號塊的代碼點,所以它們最不容易過濾。然而,在這個范圍之外還有一些其他的特殊代碼是不可見的,比如蒙古文元音分隔符(U+180E)。
通常,使用Unicode對唯一性約束進行簡單的字符串比較是很危險的。潛在的解決方法是限制標識符允許的字符集以及可能被欺詐分子濫用的任何其他數據。不幸的是,這并不能完全解決問題。
2、許多代碼點看起來非常相似
為了覆蓋世界上所有書面語言所使用的所有符號,Unicode不得不具有許多類似的字符,以至于人們無法區分這些字符,但計算機區分差異時則毫無問題。此問題導致了大量濫用Mimic——這是一個有趣的工具,用外觀類似的Unicode字符替換軟件開發中使用的常見符號,如冒號和分號。它可以造成代碼編譯工具中的混亂,讓開發人員感到困惑。
符號外觀類似的問題遠遠不止是簡單的惡作劇而已。雖然有點奇怪被稱為是同態攻擊,但這些漏洞確實可能會導致嚴重的安全問題。2017年4月,一名安全研究人員通過混合來自不同字符集的字母,注冊了一個與*** .com非常相似的域名,甚至獲得了SSL證書。所有的主要瀏覽器都高高興興地顯示了SSL掛鎖,并將域名列為是安全的。
與混合可見和不可見字符類似,很少有任何理由允許在標識符中使用混合字符集名稱,尤其是域名。大多數瀏覽器已采取措施懲罰混合字符集的域名,將它們顯示為十六進制Unicode值,這樣用戶就不會輕易混淆。如果你要向用戶,例如在搜索結果中,顯示標識符,那么考慮一些類似的方法以防止混淆。但是,這也不是一個完美的解決方案。某些域名,如sap.com或chase.com完全可以很容易地從非拉丁字符集的單個塊中構建起來。
Unicode聯盟發布了一個容易混淆的字符列表,可用于自動檢查山寨貨。另一方面,如果你想尋找創建混淆的快速路徑,那么請看Shapecatcher——這是一個奇妙的工具,它列出了看上去類似繪圖的Unicode符號。
3、規劃化其實不規范
規范化對于如用戶名等標識符非常重要,可以幫助用戶雖以不同的方式輸入值,但能一致地處理它們。規范標識符的常用方法是將所有內容都轉換為小寫,例如,確保JamesBond與jamesbond相同。
由于有如此多的相似字符和重疊集合,不同的語言或unicode處理庫可能會應用不同的規范化策略,這會潛在地開放安全風險,如果規范化在幾個地方完成的話。簡而言之,不要認為小寫變換在應用程序的不同部分中是一樣的。來自Spotify的Mikael Goldmann在他們的一個用戶發現劫持賬戶的一個方式之后,于2013年就此問題寫了一篇很贊的事件分析。攻擊者可以注冊其他人的用戶名(例如 ???????)的unicode變體,這些用戶名將被轉換為相同規范的帳戶名(bigbird)。應用程序的不同層次對字詞進行不同的規范化處理——允許用戶注冊惡意帳戶,但是會重置目標帳戶的密碼。
4、屏幕顯示長度和內存大小沒有關系
使用基本的拉丁文和大部分歐洲的字符集時,屏幕或紙張上的文本空間大致與符號數量成正比,與文本的內存大小大致也成正比。這就是為什么EM和EN是流行的單位長度。然而通過Unicode,任何類似的假設都會變得危險。有一些可愛的符號,比如Bismallah Ar-Rahman Ar-Raheem(U+FDFD),此單個字符比大多數英文單詞都要長,因此很容易在網站上跳出假定的視覺封閉。這意味著基于字符串字符長度的任何類型的換行或文本中斷算法都可能輕易被愚弄。大多數終端程序需要固定寬度的字體,所以在其中一個顯示的話,你將在完全錯誤的地方看到結束引號。
對此有一個濫用就是zalgo文字生成器,在文本片段周圍添加圍繞著的垃圾,而這些垃圾將占據更多的垂直空間。
當然,隱藏代碼點的整個問題使得內存大小與屏幕長度無關,所以可以很好適合輸入域的東西可能足以炸毀數據庫領域。過濾非視覺字符以防止出現問題是不夠的,因為還有很多其他不占用空間的例子。
結合拉丁字符(例如U+036B和U+036C)占據上一個字母的空格,這樣你可以在單個文本行中寫入多行文本(’N\u036BO\u036C’生成N?O?)。用來表示希伯來語圣經儀式吟誦的語調標記可以無限地堆疊在同一個視覺空間中,而這意味著它們可以輕易被濫用,會導致編碼大量信息到屏幕上占據單個字符的內容上。Martin Kleppe編碼了針對瀏覽器語調標記的《Conway’s Game of Life》的實現。查看頁面的源代碼,很不錯。
5、Unicode不僅僅是被動數據
一些代碼點旨在影響可輸出字符的顯示方式,這意味著用戶可以復制和粘貼的不僅僅是數據——也可以輸入處理指令。一個常見的惡作劇是使用從右到左覆蓋(U+202E)來切換文本的方向。例如,用谷歌地圖搜索Ninjas。查詢字符串實際上會翻轉搜索詞的方向,盡管頁面的搜索字段中顯示的是“ninjas”,但實際上它搜索的是“sajnin”。
這個漏洞是如此受歡迎,以致于甚至成為了XKCD。
混合數據和處理指令——可有效執行的代碼——絕不是一個好主意,特別是如果用戶可以直接輸入的話。這對于包含在頁面顯示中的任何用戶輸入來說,都是一個大問題。大多數Web開發人員都知道通過刪除HTML標簽來清理用戶輸入,但輸入中的Unicode控制字符也需要注意。這是解決任何形式的臟話或內容過濾的簡單方法——只需要向后翻轉單詞,在開始處包含從右到左的覆蓋。
從右到左的編輯可能無法嵌入惡意代碼,但如果不小心的話,可能會破壞內容或翻頁。防止這種情況的常用方法是將用戶提供的內容放入輸入字段或文本區域,這樣處理指令不會影響頁面的其余部分。
另一個關于顯示特別有問題的處理指令類型是字形變換選取器。為了避免為每個表情符號的每個顏色變體創建單獨的代碼,Unicode允許使用變換選擇器將基本符號與顏色混合。白色旗幟、字形變換選取器和彩虹通常會產生彩虹色的旗幟。但并非所有的變換都是有效的。2017年1月,iOS unicode處理中的一個bug使得惡作劇者可以通過發送特制消息來遠程崩潰iPhone。消息包含白色旗幟,字形變換選取器和一個零。這時,iOS CoreText會進入應急模式——嘗試選擇正確的變體,并使操作系統崩潰。此惡作劇作用于直接信息、分組聊天,以及甚至共享聯系人卡片。這個問題對iPad,甚至一些MacBook電腦也有影響。對此,我們幾乎束手無策。
類似的bug每隔幾年就會發生一次。2013年,阿拉伯字符處理的bug——可能會導致OSX和iOS崩潰——浮出水面。所有這些錯誤都深深埋藏在OS文本處理模塊中,所以典型的客戶端應用程序開發人員根本無法阻止。
關于其他有趣的處理指令,請查看GitHub上的Awesome Codepoints列表。對于Unicode造成的更多混亂,請查閱我寫的《Humans vs Computers》一書。
來自:碼農網,英文原文,譯者:小峰
開發者
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。