2009年6月13日土曜日

全然意識したこと無かったけど

ASP.NET MVCだからどうのこうのっていう話ではないんだけど、ちょっと衝撃。

ASP.NET MVC Routing vs. Reserved Filenames in Windows - Stack Overflow

↑ここで初めて目にした時は"へぇ~"くらいだった。

bitquabit - Zombie Operating Systems and ASP.NET MVC

↑ここで2回目に目にした時は"マジやべ~"に変わった。デフォルトルート設定のままCom1Controllerを作ってアクセスしてみた。

ng1

ぬふ。404ですね。普通に開発してたら、Com1Controllerなんて作ったりしないから平気だろう、なんて甘いこと考えてたらダメですよ!

続いて、HomeControllerのIndexアクションを以下のようにしてみましょう。普通です。

    public ActionResult Index(string id)
    {
      ViewData["id"] = id;

      return View();
    }

で、Home/Index.aspxにこれまた以下のようなコードを書いたとしましょう。

  <p>
  id="<%= Html.Encode(ViewData["id"]) %>"
  </p>
  
  <div></div>
  <dl>
    <dt>ダメなパターン</dt>
    <dd>
    <%
      foreach (var id in new[]{"COM","LPT"}.SelectMany(
              l=>Enumerable.Range(1, 9).Select(r=>l+r))
                           .Union(new[]{"CON","AUX","PRN","NUL"}))
        Response.Write(Html.ActionLink(id, "Index", new { id }) + " ");
    %>
    </dd>
    <dt>いいパターン</dt>
    <dd>
    <%
      foreach (var id in new[] { "COM0", "COM1029", "id", "PRINTER", "NULL" })
        Response.Write(Html.ActionLink(id, "Index", new { id }) + " ");
    %>
    </dd>
  </dl>

ワクワクしますな。ドキドキが止まりませんな。

ng2

こんなのが表示されますね。もうあからさまに怪しいのが見てとれます。早速リンクをクリックしてみようじゃないですか。

まずは、下段の"COM0"。普通上段からだよ...。まぁ、いいでしょう。

ng3

ちゃんと出ます。続いて"COM1209"、"NULL"も試してみたけどちゃんと出ます。

今度は上段の"COM1"。

ng4

ぎゃふーん!!

でも、変な値が出るわけじゃないから、まぁいいか。そんなURL入れるのが悪い!なんて思ってたら変な障害出たりしてあたふたすることになりかねないですよ!だって、IDに文字列入力許すような設計って普通じゃないですか。んで、ルーティングのパラメータにID含むようなURL設計って当たり前すぎるじゃないですか。でも、ID入力時に"COM1"やら"NUL"やら"AUX"やらはじくような処理を入れるのが当たり前なわけじゃないじゃないですか。当たり前なんですか?そーだったらすいません。

何となくRouteCollection.RouteExistingFiles プロパティ (System.Web.Routing)でtrueにしてみたけど、ダメだったから、そういうもんだとして入力値のチェックをちゃんとやろうと思うところです。