【问题标题】:ASP.NET Normalizing Backslashes to Forward SlashesASP.NET 将反斜杠规范化为正斜杠
【发布时间】:2012-11-29 11:07:41
【问题描述】:

ASP.NET 正在将请求路径中的反斜杠“规范化”为正斜杠,我需要它们作为反斜杠出现(它用于在数据库中执行查找)。我不介意转义的正斜杠是否未转义,这与 this question 不同。

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进行这种规范化吗?

【问题讨论】:

标签: c# asp.net asp.net-mvc-4


【解决方案1】:

简答

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

调查

我想通过反编译运行时并遵循代码来调查此问题。这样做总是很好:您了解运行时的工作原理,有时您会发现问题。让我们开始旅程吧……

作为起点,我使用 ILSpy 反编译 System.Web,从 HttpRuntime 类开始。浏览public static void ProcessRequest(HttpWorkerRequest wr)ProcessRequestNoDemandProcessRequestNowProcessRequestInternal...

这里我想调查以下几行:
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 的事情?)。

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

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

结论

http 运行时正在杀死你的反斜杠,没有任何记录的原因。您无法禁用此行为。

解决方法 #1

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

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

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

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

搜索HttpRequestUrl.OriginalStringRawUrlPathServerVariables 均不包含所需的值。甚至没有 _filePath_path_queryStringText_rawUrl_rewrittenUrl_url 私有字段。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 是的,他做到了。写好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2015-01-27
    • 2014-09-28
    • 2019-11-19
    • 2020-11-10
    • 1970-01-01
    相关资源
    最近更新 更多