为何Kestrel中配置的路径陷阱路由无法生效?
问题原因
ASP.NET Core(含Kestrel服务器)处理请求时会自动对URL路径做规范化处理——它会解析并移除路径里的../、./这类相对路径片段,把路径转换成标准绝对格式。
你发送的GET /../../etc/passwd请求,经过规范化后会变成/etc/passwd(假设应用部署在根路径),但你配置的路由是/../../etc/passwd,两者不匹配,所以Kestrel返回404 Not Found。
解决方案
要捕获这类原始的路径逃逸请求,得在路由匹配前通过中间件拦截请求,直接检查客户端发送的未规范化原始路径,再返回虚假响应。
具体实现代码如下:
// 要放在所有路由配置之前添加这个中间件 app.Use(async (context, next) => { // 提取原始请求路径(剔除查询字符串部分) var rawPath = context.Request.RawTarget.Split('?')[0]; // 判断是否为目标陷阱路径 if (rawPath.Equals("/../../etc/passwd", StringComparison.Ordinal)) { context.Response.ContentType = "text/plain"; await context.Response.WriteAsync(@"root:ZghOT0eRm4U9s:0:0::/:/bin/sh"); return; // 终止后续管道执行,直接返回响应 } // 非陷阱请求,继续执行后续中间件(包括路由匹配) await next(); }); // 你的其他Minimal API路由配置 app.MapGet("/", () => "Hello World!");
补充说明
HttpRequest.RawTarget属性保存了客户端发送的原始请求目标(即请求行里的路径+查询字符串),通过它能拿到未被规范化的原始路径。- 如果要捕获更多变种的路径逃逸请求(比如
/.././../etc/passwd),可以改用正则表达式匹配,示例:var trapPattern = new Regex(@"^(/\.\./)+etc/passwd$", RegexOptions.Compiled); if (trapPattern.IsMatch(rawPath)) { // 返回虚假响应逻辑 }
内容的提问来源于stack exchange,提问作者Joshua
相关产品推荐
相关产品推荐

