2017-04-10 3 views
2

ビルドしているASP.NET MVC Webサイトには、管理者がビューの下でファイルシステムにcshtmlファイルを手動で作成できる必要があるという要件がありますもちろん、コントローラの操作でそのページにアクセスすることができます。 (すなわち、その後/Content/Testを経由してアクセスし、Test.cshtmlというファイルを作成します)ASP.NET MVCのビューを動的にレンダリングする際のセキュリティの影響

私は、次のアプローチを経由して、これをやった:

まず、カスタムルートの設定:

routes.MapRoute(
      name: "StandardContent", // my controller 
      url: "Content/{pageName}", 
      defaults: new {controller = "Content", action = "Render", pageName = UrlParameter.Optional} 
     ); 

そして、コントローラのアクションビュー名をパラメータとして取得し、要求されたビュー名が存在するかどうかをチェックしてビューをレンダリングします。

public ActionResult Render(string pageName) 
{ 
    if (pageName.IsNullOrEmpty()) 
    { 
     return RedirectToAction("Index", "Home"); 
    } 

    // if no view exists with this name, go 404 
    if (!this.ViewExists(pageName)) // my extension method for view checking 
    { 
     return RedirectToAction("NotFound", "Error"); 
    } 

    return View(pageName); 
} 

私はそれがセキュリティの意味を除いて満足しています。ここで私は基本的には何でも生の入力ユーザーがURLに書き込み、その入力にビューが存在するかどうかをチェックしています。ユーザは通常、という悪質なパラメータを書いて、通常は制限付きアクセス(例:接続文字列ファイル)になるファイルにアクセスできる可能性がありますか?もしそうなら、私はそれをどのように防ぐべきですか?それは場合に役立ちます。ここ


は、拡張メソッドthis.ViewExists(pageName)ためのコードです。

public static bool ViewExists(this Controller controller, string viewName) 
{ 
    var result = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, null); 
    return result.View != null; 
} 

答えて

2

私のアプリケーションでは同じ機能を持ち、単純に正規表現チェックを追加してよりよくスリープ状態にしました。
あなたは、単にあなたのViewExistsメソッドに追加することができます:

public static bool ViewExists(this Controller controller, string viewName) 
{ 
    // check for viewName null or empty here? 

    if (!Regex.IsMatch(viewName, "^[A-Za-z0-9_]+$")) 
     throw new HttpException(404, "Not found"); 

    var result = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, null); 
    return result.View != null; 
} 

(私の場合には、文字、数字、およびアンダースコア(_))のみ許可されたシンボルを使用してくださいあなたのビューのファイル名に。私として


、私はベースコントローラクラスにこのメソッドをincapsulated:

public class BaseController : Controller 
{ 
    public ActionResult DynamicView(string viewName) 
    { 
     if (string.IsNullOrWhiteSpace(pageName)) 
      return RedirectToAction("Index", "Home"); 

     if (!Regex.IsMatch(viewName, "^[A-Za-z0-9_]+$")) 
      return RedirectToAction("NotFound", "Error"); 

     var result = ViewEngines.Engines.FindView(ControllerContext, viewName, null); 
     if (result.View == null) 
      return RedirectToAction("NotFound", "Error"); 

     return View(viewName); 
    } 
} 

を次に、あなたはこのBaseControllerからすべてのコントローラを継承する場合は、あなたが必要なとき、あなたはこのワンライナーを使用することができます。

public ActionResult Render(string pageName) 
{ 
    return DynamicView(pageName); // short, simple and reusable 
} 

BaseControllerは一般的に便利なものであり、多くの有用なMVCロジックをカプセル化することができます。

+0

美しくて素敵で、ありがとう! :) –

関連する問題