ASP.NET MVC 5 預設的資安機制
2020-09-27
本次的筆記源自於 ASP.NET: Security 課程的啟發,其中討論了關於 OWASP 中常見的弱點以及其在 ASP.NET MVC 中可能出現的方式。而實際上學習的心得發現 ASP.NET MVC 有相當程度的預設的安全機制,而瞭解這些機制與 OWASP 中常見的弱點,可以更有安全開發的意識。
說明
XSS Defense Default
預設情形下在 ASP.NET MVC 中不容易遇見 XSS ,但如果有特殊的需求放行特殊的字元或將特殊字元置於特別的程式位置,則就有可能有 XSS 的疑慮。
ASP.NET MVC XSS 關鍵字
- [ValidateInput(false)]
- allowHtml
- HttpUtility.encode
- Html.Raw
本段程式碼為允許 XSS 傳入的 Action 範例,如果直接在 View 中以 Html.Raw 渲染, XSS 就可以被實現。
[ValidateInput(false)]
public ActionResult DefaultDefense(string query)
{
ViewBag.query = query;
return View();
}
HttpUtility.JavaScriptStringEncode
預設情形下,JS 會自動渲染傳入的 escape sequences,藉由 JavaScriptStringEncode 則可以加以編碼 escape sequences 讓其不被渲染。
escape sequences examples:
. : \x2e
/ : \x2f
\ : \x5c
< : \x3c
> : \x3e
UTF-8 encoding table and Unicode characters
malicious query : \x3cscript\x3ealert(1)\x3c/script\x3e
<div id="xss"></div>
@section scripts{
<script>
$('#xss').html('@ViewBag.query')
</script>
}
藉由 JavaScriptStringEncode 則可以加以編碼 escape sequences 讓其不被渲染。
ViewBag.query = HttpUtility.JavaScriptStringEncode(query);
⚠️直接將使用者輸入的內容放入 js script 中相當危險,JavaScriptStringEncode 雖可針對 escape sequences 編碼,但 html tag 則不會處理,所以如果有使用 jQuery.html 之類的函式時,也必須一併檢查是否包含不當的 html tag。
SQL Injection
原則上使用 Entity Framework 不受 SQL Injection 的影響,但仍能夠使用 Entity Framework 對於資料庫進行直接的指令查詢:
DbSet.SqlQuery();
DbContext.Database.SqlQuery();
DbContext.Database.ExecuteSqlQuery();
原因上避免這樣的使用,而如果有特殊的使用原因,務必要檢查使用者輸入的內容以及是否被直接傳送到 SqlQuery() 中。
Cross Site Request Forgery, CSRF
在 Post 的情境下 ASP.NET MVC 會自動生成 ValidateAntiForgeryToken,但如果 Custom Get Action 有直接影響資料庫內容時,可以考慮改為 Post 加上 ValidateAntiForgeryToken,但如果,或者在參數上加上 ValidateAntiForgeryToken,避免 Cross Site Request Forgery。
view
@using (Html.BeginForm("Action", "Controller")){
@Html.AntiForgeryToken()
}
controller
[ValidateAntiForgeryToken]
public ActionResult Action(){ }
Web.config Encryption
Encryption
使用系統管理員身分執行 Command-line
cd "folder with web.config to encrypt"
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pef connectionStrings "."
Decryption
cd "folder with web.config to decrypt"
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pdf connectionStrings "."
黑暗執行緒 - web.config連線字串加密工具
使用相同 RSA 金鑰容器幫 web.config 連線字串加密
Secure Configuration
Secure cookies & sessions
<system.web>
<sessionSate
cookieless="false"
regenerateExpiredSessionId="false"
timeout="20"
/>
<httpCookies
httpOnlyCookies="true"
requireSSL="true"
sameSite="Strict"
/>
</system.web>
更完整與詳盡的整合筆記,可以參考下列連結:ASP.NET Web.config & Http Headers 安全設定大全
其他參考資料
什麼!? SameSite Cookies Policy 更新了— Chrome SameSite Attribute 簡介
Error Handling
Custom Error Handler
void Application_Error(){
var ex = Server.GetLastError();
}
Custom Error Message
<customErrors mode="On">
<error statusCode="404" redirect="~/Home/Error">
</customErrors>
Security HTTP Headers
Global.asax
void Application_Start(object sender, EventArgs e)
{
MvcHandler.DisableMvcResponseHeader = true;
}
Enforcing HTTPS
- Redirect
- Rewrite
- HSTS
Rewrite
<system.webServer>
<rewrite>
<rules>
...
本段落規劃獨立成個別筆記,從 HTTPS 前世今生到強制使用 HTTPS 😊
後續行動
安全的上傳機制,避免被上傳 webshells
本次課程的遺憾是未討論安全檔案上傳方式,這個部分待日後藉由 ASP.NET專題實務(I):C#入門實戰 來補充知識,並且知行合一的再將實作結果另外筆記。
參考 OWASP - File Upload Cheat Sheet 實作安全的上傳機制
使用 Shell-Detector 定期自主檢查服務是否存在 webshells ,同時尋找更好的評斷工具與標準。