歡迎光臨
每天分享高質量文章

關於 Unicode 每個程式員應該知道的 5 件事

譯者:小峰,出處:碼農網

鏈接:codeceo.com/article/5-things-every-programmer-know-about-unicode.html

Unicode是一個令人難以置信的有用標準,它能使全世界的計算機、智慧手機和智慧手錶以同樣的方式顯示相同的信息。不幸的是,它的複雜性使它成為了欺詐分子和惡作劇的金礦。

正文共:3754 字 

預計閱讀時間:10 分鐘

之前曝出了山寨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月,一名安全研究人員通過混合來自不同字符集的字母,註冊了一個與apple.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ͫOͬ’生成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》一書。


●本文編號607,以後想閱讀這篇文章直接輸入607即可

●輸入m獲取文章目錄

推薦↓↓↓

Web開發

更多推薦18個技術類微信公眾號

涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂