我們有個 ASP.NET MVC 專案上周在做程式碼安全性檢查 Code Review 時,發現開發人員在 Razor 頁面中使用了一些 @Html.Raw() 輸出未經 HTML 編碼的內容,正常來說,在 ASP.NET MVC 網站應用程式中,不應該太過頻繁地出現這種用法,所以只要看到就會特別查看一下,這才發現原來 Razor 從 V2 版開始,就存在著這個小問題 (Bug),所以大家還是要注意一下。
我先來描述一下問題:
基本上,你要在 Razor 頁面中顯示 @ 符號,只要寫上兩的 @ 符號就可以直接輸出 @ 符號,如下圖示:
從上圖你可以看到
- 第 2 行是個例外,因為 Razor 會自動判斷 @ 是不是 Email 格式,如果符合 Email 格式的話,就會自動跳脫 (Escape) 這個 @ 符號,不會把它當成伺服器內容輸出。
- 第 4 行則是標準寫法,直接用 @@ 來輸出一個 @ 符號。
- 第 6 行則是透過 @ 正常輸出一個伺服器端變數 ( ViewBag.Url )
- 第 19 行則是今天的重點,他在 Visual Studio 裡面出現了錯誤提示!
如果硬是要把網站執行起來,你會看到以下錯誤:
"@" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid.
這就很奇怪了,因為只要你想把 @ 字元出現在 Attribute 中,就會出現這個問題,而我們這個客戶,還真的需要將 @ 符號寫在 name 屬性中!
因為你怎樣嘗試,就是無法正常輸出 @ 字元在 HTML 中,都會發生錯誤,所以負責這段程式碼的工程師寫成以下格式:
- <param name="@Html.Raw("@videoPlayer")" value="4642134676" />
雖然這段程式碼並無安全問題,畢竟這次要輸出的 @videoPlayer 只是個靜態字串而已,但出現 @Html.Raw 我認為就是不太妥當,大家最好不要養成使用 @Html.Raw 的習慣。
所以修改的方法,我認為還有以下 2 種,總之就是比用 @Html.Raw 好一些:
- <param name="@("@videoPlayer")" value="4642134676" />
- <param name="@("@")videoPlayer" value="4642134676" />
此問題從 Razor V2 開始出現,直到 Razor V3 依然存在,不過剛查到 Razor V4 beta5 已經修正此問題了,各位可能要等到 ASP.NET MVC 6 ( Razor V4 ) 才能正常在 HTML 屬性中使用 @@ 來輸出一個 @ 字元! ^^
相關連結