真糟糕,知名的「許功蓋」又再次重出江湖,這次出現的地方竟然是 URLScan 工具,我知道有許多專業網管人員都會安裝 URLScan 到網站主機用以提供基礎網站安全防禦,但是當遇到開發人員將網站開發完要上線時無辜的被 URLScan 阻擋時,不瞭解的網管或客戶還可能會以為是程式出問題,而讓軟體工程師改程式改到地老天荒…
不管是大五碼(Big5)或是 GB2312 碼,這些 CJK 字碼都是在非常有限的字碼中用來表達中文字的字元,我們又通稱為雙位元(Double Byte)字元,也就是一個中文字包括兩個 ANSI 字元所組成,第一個 ANSI 字元我們稱為高位位元組(High Byte),第二個 ANSI 字元我們稱為低位位元組(Low Byte)。
以大五碼為例,中文字定義的字碼與可使用範圍如下圖所示:
各位應該知道 ASCII 字元定義的範圍是從 0x00 - 0x7F,而中文字定義的字碼,在高位位元組(High Byte)的部分至少都是從 0x81 開始,所以不會與 ASCII 有任何衝突。但是在 低位位元組(Low Byte) 的地方卻定義了 0x40 ~ 0x7E 與 0xA1 ~ 0xFE 的區間,所以在 0x40 ~ 0x7E 這個區間將會有七千多個中文字會用到「部分」ASCII 碼!
我們回到 URLScan 的預設設定中,你會發現有個 [DenyUrlSequences] 區段設定,其中定義了一個「反斜線 ( \ )」字元,其字元的 ASCII 的十六進制表示的數值為 0x5C
我做了一個簡單的測試,首先我的 IIS 有安裝 URLScan 工具並確認啟用,然後在我的 IIS 預設站台根目錄下新增一個網頁名為 "成功.htm"
在 Internet Explorer 中輸入網址為:http://localhost/成功.htm
事實上我們從 Server 端收到的 Request 會被 IE 進行 UrlPathEncode 過,所以正確的 Request 路徑應為:http://localhost/%E6%88%90%E5%8A%9F.htm
眼力好的人應該看的出來,"成功" 被代換成 UTF-8 編碼了,其中 "%E6%88%90" 是 "成",而 "%E5%8A%9F" 是 "功",然後你會得到一個 "HTTP 錯誤 404.0 - Not Found 您尋找的資源已移除、名稱已變更,或暫時無法使用。" 的錯誤訊息。
然後我們到 C:\Windows\System32\inetsrv\urlscan\logs 目錄下查看最新的 URLScan 阻擋紀錄,你應會看到 "Rejected disallowed+URL+sequence URL" 錯誤訊息:
GET /%E6%88%90%E5%8A%9F.htm Rejected disallowed+URL+sequence URL - \
網管人員光是看到這些訊息應該完全抓不到任何頭緒,不熟悉文字編碼的網管找到死都找不出問題所在!
由於 Windows 系統內建文字編碼的轉換,在 Windows 檔案系統中有許多的檔案,有的檔名直接以系統預設 ANSI 編碼 (Big5),有的檔名直接以 Unicode 編碼,不過使用者的確可以不用知道這些細節,因為 99.9% 的情況下,這些轉換都是自動完成的,而且大多不會影響現有 Windows 程式的運作。
大部分的情況下,檔名都是以 預設 ANSI 編碼 (Big5) 表示的,也就是說雖然你的 HTTP Request 送到 IIS 的時候是 %E6%88%90%E5%8A%9F.htm (Unicode),但是實際上 Windows 應用程式在內部作業卻會收到 %a6%a8%a5%5c.htm (Big5),而這就是問題最關鍵的地方,因為網址中出現了致命的 %5c 字元 ( \ ),以致於被 URLScan 檔下,使網頁無法顯示!
"反斜線 ( \ )" 對英語系國家的人來說並不是在網址中常見的字元,反而經常出現在網路攻擊事件中,所以會將 "反斜線 ( \ )" 列為不允許出現的字元。但是對亞洲語系的網站來說,卻是經常出現,尤其是網頁或檔案中有出現中文的地方,雖然在 Big5 中最多只有 116 個字會出現 "反斜線 ( \ ) ( %5c )",但總是會有人遇到的 。
莫非定律 ( Murphy's law )
任何有可能出錯的事將會出錯 ( Anything that can go wrong will go wrong.)
我個人建議可以將 "反斜線 ( \ )" 從 URLScan 的 [DenyUrlSequences] 區段中移除,此問題就自然迎刃而解。光是移除這個 \ 字元應該不至於對你的網站造成多大的資安風險,我覺得資安人員可以不用過於擔心調整這個預設設定。
相關連結