ASP.NET规范化反斜杠以转发斜杠

Jon*_*son 11 c# asp.net asp.net-mvc-4

ASP.NET在请求路径中"正常化"反斜杠以转发斜杠,我需要它们作为反斜杠(它用于在数据库中执行查找).我不介意如果没有转义,转义为正斜面的转义是不是这个问题.

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

请注意,我已设置事务以匹配路径的其余部分.

我尝试了以下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

当他们点击我的Web API方法时,他们就是全部mscorlib.pdb/DFA83312EAB84F67BD225058B188F22B1/mscorlib.pdb.我检查了当前的情况HttpContext,看起来ASP.NET正在进行这种规范化(而不是MVC4).

可能的解决方案:

  • 插入事务时将'\'标准化为'/',这样无论ASP.NET通过什么查找都会成功.看起来有点臭
  • Base64编码{*transaction}部分,如果它包含一个反斜杠.不是真正的地址栏hackable

有关如何让ASP.NET 进行此规范化的任何想法?

San*_*ock 4

简短回答

您无法阻止此行为,因为它被硬编码到 IIS 中。

调查

我想通过反编译运行时并跟踪代码来调查这个问题。这样做总是好的:您了解运行时是如何工作的,有时您会发现问题。让我们开始旅程吧...

作为起点,我使用 ILSpy 反编译 System.Web,从 HttpRuntime 类开始。浏览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)

最后一个(不安全)方法正在对路径执行某些操作。首先,每个字符都有一个循环。如果某个字符位于“.”下方,且不同于“/”且等于“\”,则flag = true. 循环之后,if (flag)( src ),则可能会抛出异常,并且virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);( src )。

目前看来没有什么可以帮助我们避免去那里(也许是 eurl 的事情?)。

( string FixVirtualPathSlashes(string virtualPath)src )将反斜杠替换为斜杠,并且 if 删除重复的斜杠。耻辱。

方法又如何呢GetEurl?当你阅读src时,你会发现这对你没有帮助。

结论

http 运行时正在无缘无故地杀死你的反斜杠。您无法禁用此行为。

解决方法#1

现在,一定有办法。引用此页面的这个人有一个解决方法。看来使用重写模块,您可以将原始 URL 放回到管道中。我真的不喜欢这个解决方案,因为我不知道到底发生了什么。我有另一个想法...

我还没有测试这个东西。你可以吗?

正在寻找解决方法#2(未找到)

如果有一个地方存放了原始请求路径怎么办?

搜索、 、、HttpRequest均不包含所需值。甚至连, , , , ,私有字段也不行。Url.OriginalStringRawUrlPathServerVariables_filePath_path_queryStringText_rawUrl_rewrittenUrl_url

搜索到IIS7WorkerRequest,该值已在运行时更改。我怀疑 IIS 在将请求推送到 ASP.NET 运行时之前正在执行此操作。看来是没有希望了。