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

当他们点击我的 Web API 方法时,他们都是mscorlib.pdb/DFA83312EAB84F67BD225058B188F22B1/mscorlib.pdb. 我检查了电流HttpContext,看起来 ASP.NET 正在执行此规范化(不是 MVC4)。

可能的解决方案:

  • 插入事务时,将“\”规范化为“/”,这样无论 ASP.NET 通过什么查找都会成功。好像有点臭
  • Base64{*transaction}包含反斜杠的部分。不是真正的地址栏可破解

关于如何让 ASP.NET进行这种规范化的任何想法?

4

2 回答 2

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)

最后一个(不安全的)方法正在对路径做一些事情。首先,每个字符都有一个循环。如果 char 低于 '.',并且不同于 '/' 并且等于 '\',则flag = true. 在循环之后,if (flag)src),然后可能会引发异常,并且virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);src)。

现在似乎没有什么可以帮助我们避免去那里(也许是 eurl 的事情?)。

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

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

结论

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

解决方法 #1

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

我还没有测试这个东西。你能?

搜索解决方法 #2(未找到)

如果有存放原始请求路径的地方呢?

搜索, , ,中HttpRequest没有一个包含所需的值。甚至没有, , , , ,私有字段。Url.OriginalStringRawUrlPathServerVariables_filePath_path_queryStringText_rawUrl_rewrittenUrl_url

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

于 2017-04-11T17:13:41.427 回答
-1

在发出请求之前,您是否尝试过将 UrlEncode() 应用于路径?

于 2012-12-15T00:10:19.633 回答