ASP.NET MVC 5 預設的資安機制


  1. 說明
    1. XSS Defense Default
      1. HttpUtility.JavaScriptStringEncode
    2. SQL Injection
    3. Cross Site Request Forgery, CSRF
    4. Web.config Encryption
    5. Secure Configuration
      1. Secure cookies & sessions
      2. Error Handling
      3. Security HTTP Headers
      4. Enforcing HTTPS
  2. 後續行動
    1. 安全的上傳機制,避免被上傳 webshells

本次的筆記源自於 ASP.NET: Security 課程的啟發,其中討論了關於 OWASP 中常見的弱點以及其在 ASP.NET MVC 中可能出現的方式。而實際上學習的心得發現 ASP.NET MVC 有相當程度的預設的安全機制,而瞭解這些機制與 OWASP 中常見的弱點,可以更有安全開發的意識。

logo

說明

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 讓其不被渲染。

JS 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

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

How Sessions Work

<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 ,同時尋找更好的評斷工具與標準。