Open redirect via `//<host>/..%2f<dir>` in directory trailing-slash redirect
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 78/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- javascript, node.js
調査の方向性
lib/core/index.js の decodePathname(parsed.pathname) と、Location ヘッダーを構築するディレクトリの末尾スラッシュリダイレクトから始めてください。提示されたリクエスト形式を使って回帰テストを追加し、リダイレクトがサーバーのオリジン上に留まり、先頭のスラッシュが1つだけであることを確認してください。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 ファイルあり
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
http-party/http-server のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
http-party/http-server#977 · リアクション 2 件 ·
-
難易度 5/5 1週間以上 初心者へのやさしさ 8/100
http-party/http-server#980 · コメント 2 件 ·
-
New chetオープン
難易度 5/5 1週間以上 初心者へのやさしさ 10/100
http-party/http-server#976 ·
-
Dreams local boyオープン
難易度 5/5 1週間以上 初心者へのやさしさ 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
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
guybedford/es-module-lexer#266 ·
-
bug documentation
難易度 1/5 1〜3時間 初心者へのやさしさ 88/100
apify/apify-docs#3206 ·
メンテナーはふだん 1 日以内に返信
-
enhancement good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
anhnt256/cursor-swarm#21 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
documentation good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
zerohourzulu/irontrellis#16 ·