Open redirect via `//<host>/..%2f<dir>` in directory trailing-slash redirect
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 78/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- javascript, node.js
调研方向
从 lib/core/index.js 中的 decodePathname(parsed.pathname) 和构建 Location 标头的目录尾部斜杠重定向处开始。使用提供的请求形式添加回归测试,并确认重定向仍位于服务器源站,且只有一个前导斜杠。issue 未指定测试文件,因此先找到现有的重定向测试,并运行相关测试套件。
由索引模型根据 Issue 内容生成。
描述
In http-server 14.1.1 and master (0d3b7bb, Node.js v26.13.0), requesting a path starting with //<host>/..%2f<subdir> when the served root contains <subdir> returns a 302 redirect with a scheme-relative Location header (//<host>/..%2f<subdir>/) that browsers resolve to http://<host>/..%2f<subdir>/ (CWE-601; incomplete fix for ecstatic advisory GHSA-9q64-mpxx-87fg).
const httpServer = require('http-server');
const fs = require('fs');
fs.mkdirSync('./test-root/dir', { recursive: true });
const server = httpServer.createServer({ root: './test-root' });
server.listen(0, '127.0.0.1', async () => {
const { port } = server.server.address();
const url = `http://127.0.0.1:${port}//evil.example/..%2fdir`;
const res = await fetch(url, { redirect: 'manual' });
const loc = res.headers.get('location');
console.log('Status:', res.status);
console.log('Location:', loc);
console.log('Resolved URL:', new URL(loc, url).href);
server.close();
});
Expected: Location is a single-slash origin-relative path (e.g. Location: /dir/) that stays on http://127.0.0.1:<port>/.
Actual:
Status: 302
Location: //evil.example/..%2fdir/
Resolved URL: http://evil.example/..%2fdir/
Reference: RFC 9110 §10.2.2 (Location header field) and WHATWG URL Standard §4.4 (a relative-URL string beginning with // is parsed as a scheme-relative-special-url whose host is the authority following //); see also GHSA-9q64-mpxx-87fg and commit jfhbrook/node-ecstatic@be6fc25.
In lib/core/index.js, decodePathname(parsed.pathname) decodes %2f and normalizes //evil.example/../dir to pathname = '/dir' (matching the local directory without a trailing slash), but the 302 response constructs Location from the unnormalized parsed.pathname (ensureUriEncoded(${parsed.pathname}/${q})) instead of pathname or a path with leading slashes collapsed ('/' + parsed.pathname.replace(/^[\/\\]+/, '')).
Credit: https://ucsbplse.github.io/
- 主要语言
- JavaScript
- 星标
- 14.2k
- 派生
- 1.6k
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 提供 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
http-party/http-server 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
http-party/http-server#977 · 2 个 reaction ·
-
难度 5/5 一周以上 新手友好度 8/100
http-party/http-server#980 · 2 条评论 ·
-
New chet未关闭
难度 5/5 一周以上 新手友好度 10/100
http-party/http-server#976 ·
-
Dreams local boy未关闭
难度 5/5 一周以上 新手友好度 15/100
http-party/http-server#975 ·
-
难度 4/5 3-5 天 新手友好度 48/100
http-party/http-server#973 · 3 条评论 ·
查看 http-party/http-server 的全部 Issue
相似的 Issue
-
bug web-ui
难度 2/5 1-3 小时 新手友好度 67/100
jenkinsci/jenkins#27705 · 3 条评论 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 70/100
maproulette/maproulette-frontend#2978 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
live-codes/livecodes#1079 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 1 天内回复
-
approved check:passed logos:add
难度 1/5 1 小时以内 新手友好度 74/100
维护者通常 2 天内回复