11

ASP.NETは、スラッシュを転送するための要求パスのバックスラッシュを「正規化」しており、バックスラッシュとして通過する必要があります(データベースでのルックアップを実行するために使用されます)。この質問とは異なり、エスケープされたスラッシュがエスケープされていないものとして通過してもかまいません。

config.Routes.MapHttpRoute(
    name: "TransactionsApi",
    routeTemplate: "api/transactions/{*transaction}",
    defaults: new { controller = "transactions", transaction = RouteParameter.Optional }
);

パスの残りの部分と一致するようにトランザクションを設定したことに注意してください。

次のURLを試しました(ブラウザーとFiddlerの両方から)。

  • api/transactions/mscorlib.pdb\DFA83312EAB84F67BD225058B188F22B1\mscorlib.pdb
  • api/transactions/mscorlib.pdb\\DFA83312EAB84F67BD225058B188F22B1\\mscorlib.pdb
  • api/transactions/mscorlib.pdb%5CDFA83312EAB84F67BD225058B188F22B1%5Cmscorlib.pdb
  • api/transactions/mscorlib.pdb%5C%5CDFA83312EAB84F67BD225058B188F22B1%5C%5Cmscorlib.pdb

それらが私のWebAPIメソッドにヒットするまでに、それらはすべてmscorlib.pdb/DFA83312EAB84F67BD225058B188F22B1/mscorlib.pdbです。現在のデータを調べたところ、HttpContextASP.NETがこの正規化を行っているようです(MVC4ではありません)。

可能な解決策:

  • トランザクションを挿入するときは、'\'を'/'に正規化して、どのASP.NETがルックアップを通過しても成功するようにします。少し臭いようです
  • {*transaction}バックスラッシュが含まれている場合は、パーツをBase64で指定します。実際にはアドレスバーをハッキングできない

ASP.NETでこの正規化を行わないようにする方法について何か考えはありますか?

4

2 に答える 2

4

短い答え

IISにハードコーディングされているため、この動作を防ぐことはできません。

調査

ランタイムを逆コンパイルし、コードに従うことで、この問題を調査したいと思いました。それを行うのは常に良いことです。ランタイムがどのように機能するかを学び、時には問題を見つけることがあります。旅を始めましょう...

出発点として、HttpRuntimeクラスから始めて、ILSpyを使用してSystem.Webを逆コンパイルしています。public static void ProcessRequest(HttpWorkerRequest wr)、、、、..ProcessRequestNoDemandをナビゲートProcessRequestNowするProcessRequestInternal

ここでは、次の行を調査したいと思います:
httpContext = new HttpContext(wr, false);、、。
httpContext.Response.InitResponseWriter();
httpAsyncHandler.BeginProcessRequest(httpContext, this._handlerCompletionCallback, httpContext);

多くの場合、これHttpContext.HttpContext(HttpWorkerRequest wr, bool initResponseWriter)を引き起こす可能性があります:
this.Init(request, response)
new HttpRequest(wr, this)

より正確にHttpContext.GetEurl()は(疑わしいように見える)、
Request.InternalRewritePath(VirtualPath.Create(virtualPath), null, true)(安全)、
VirtualPath.Create(virtualPath) (非常に疑わしいように見える)、
virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);(悪名高い!)。

ここで私たちを取得するスタックトレースを書いてみましょう:

  • HttpRuntime.ProcessRequest...(複数の方法)
  • new HttpContext(wr, false)
  • this.Init(new HttpRequest(wr, this), new HttpResponse(wr, this));
  • if (!string.IsNullOrEmpty(eurl))(ifの入力を防ぐことはできますか?)
  • this.Request.InternalRewritePath(VirtualPath.Create(virtualPath), null, true);
  • VirtualPath Create(string virtualPath)
  • unsafe static VirtualPath Create(string virtualPath, VirtualPathOptions options)

この最後の(安全でない)メソッドは、パスに対して何かを実行しています。まず、各文字にループがあります。charが「。」より下にあり、「/」とは異なり、「\」と等しい場合、flag = true。ループの後にif (flag)src)、例外がスローされる場合があり、virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);src)。

今のところ、そこに行くのを避けるのに役立つものは何もないようです(多分eurlのことですか?)。

srcstring FixVirtualPathSlashes(string virtualPath) )は、円記号をスラッシュに置き換え、ifが重複するスラッシュを削除します。恥。

方法はどうGetEurlですか?srcを読むと、それは役に立たないことがわかります。

結論

httpランタイムは、文書化された理由なしにバックスラッシュを強制終了します。この動作を無効にする方法はありません。

回避策#1

今、方法があるに違いありません。このページを参照しているこの人には回避策があります。リライトモジュールを使用すると、元のURLをパイプラインに戻すことができるようです。何が起こっているのか正確にはわからないので、このソリューションはあまり好きではありません。私は別の考えを持っています...

私はまだこのことをテストしていません。あなたはできる?

回避策#2を検索しています(見つかりませんでした)

元のリクエストパスが保存されていた場所があった場合はどうなりますか?

を検索すると、、、、HttpRequestのいずれにもUrl.OriginalString目的の値が含まれていません。、、、、、、プライベートフィールドでさえありません。RawUrlPathServerVariables_filePath_path_queryStringText_rawUrl_rewrittenUrl_url

を検索するIIS7WorkerRequestと、値は実行時にすでに変更されています。リクエストをASP.NETランタイムにプッシュする前に、IISがそのことを行っているのではないかと思います。希望がないようです。

于 2017-04-11T17:13:41.427 に答える
-1

リクエストを行う前に、パスにUrlEncode()を適用してみましたか?

于 2012-12-15T00:10:19.633 に答える