使用 ASP NET Core MVC 開發時,遇到 HTML 裡的中文被進行編碼,無法正常顯示。
在找問題成因的時候,出於好奇研究了一下 ASP NET 歷史版本的更新與 View HtmlEncode 的淵源,讓我們把時間倒回 2010 年吧XD
在 ASP.NET 3.5(MVC 2) 以前,WebForm View Engine 若想要編碼 HTML 中的內容以避免 XSS 問題,需要自己呼叫編碼的方法,但是每個內容都要呼叫實在很麻煩,而且開發者也常常會忘記。
所幸 2011 年,ASP.NET 4(MVC 3)發佈以後,新增 <%: %>
語法來自動對內容進行 HTML 編碼,減輕了開發者的負擔與降低系統安全風險。
ASP.NET 4(MVC 3)版本中,也 Release 了 Razor View Engine,因為容易學習、寫法更為簡潔方便的特性,使得它逐漸成為開發 ASP.NET MVC 網站的主流(兩者具體比較可以參考)。
使用 Razor 在渲染畫面時,會自動進行編碼,防止 XSS。
簡單來說 cshtml 裡面用到任何後端帶過來的變數,為避免造成 XSS 安全問題,Net Fx 和 Net Core 都會自動對特定符號轉碼。
EX: `< > ' "`
以下可以看到測試的結果,特定的字元都被進行轉碼。
以上都沒什麼問題,但相同的測試到了 Net Core,好像有些事情不太對勁喔
輸出的結果
可以發現到,除了特定的字元以外,連中文都被編碼了,僅剩 abc123 正常顯示。
翻了一下官方文件真相大白
原來 ASP.NET Core 的 Razor TagHelper 及 HtmlHelper 預設會將所有非拉丁字元都當成特殊符號進行編碼,理由是為了防範未知或未來瀏覽器針對這些字元渲染時發生的錯誤...
解決方式也很簡單,放寬預設安全字元的限制就好。
在 Startup
中的 ConfigureServices
自訂 HtmlEncoder 安全清單,加上 CJK Unified Ideographs
。
services.AddSingleton<HtmlEncoder>( HtmlEncoder.Create(allowedRanges: new[] { UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs }));
中日韓統一表意文字(英語:CJK Unified Ideographs),也稱統一漢字、統漢碼(英語:Unihan),目的是要把分別來自中文、日文、韓文、越南文、壯文、琉球文中,起源相同、本義相同、形狀一樣或稍異的表意文字,在ISO 10646及萬國碼標準賦予相同編碼。
from wiki
本文同步發表於我的 Blog
Prevent Cross-Site Scripting (XSS) in ASP.NET Core
HTML Encoding in MVC
ASPX View Engine VS Razor View Engine
HTML Encoding Output in ASP.NET 4
ASP.NET MVC 演進歷史
ASP.NET MVC Version History