CONNECT
使い方
CONNECT リクエストは、HTTP プロキシに対して指定されたホストとポートへの TCP 接続を確立し、その後は生のバイト列を双方向に中継するよう指示します。リクエストターゲットはパスではなく authority-form(host:port)を使用します。
CONNECT の主な用途は HTTPS トンネリングです。プロキシの背後にいるクライアントが HTTPS サイトに到達する必要がある場合、処理は次の順序で進みます。
トンネルが確立されたあとプロキシは生のバイト列を転送するため、プロキシは暗号化されたトラフィックの中身を見ることができません。これは、企業やネットワークのプロキシが外部サーバーへの HTTPS アクセスを許可するために使っている仕組みです。
プロキシが認証を要求する場合、クライアントは CONNECT リクエストに Proxy-Authorization ヘッダーを含めます。資格情報が欠落しているか無効な場合は、407 Proxy Authentication Required レスポンスになります。
WHATWG Fetch Standard は CONNECT を禁止メソッドとして挙げており、JavaScript がブラウザ API を通じて CONNECT リクエストを発行することを防いでいます。
HTTP/2 と HTTP/3 では、CONNECT は TCP 接続全体ではなく単一のストリーム上にトンネルを作成します。HTTP/2 仕様は個々のストリーム向けの基本的な CONNECT を定義しています。拡張 CONNECT プロトコルアップグレードは :protocol 擬似ヘッダーを追加し、多重化された接続上で WebSocket などのプロトコルを利用可能にします。これは HTTP/2 と HTTP/3 の両方でサポートされています。基本のストリームトンネルと拡張 CONNECT は相互補完的です。前者は生のトンネリングを提供し、後者は多重化された接続上で TCP 以外のプロトコルを可能にします。
プロキシを経由する HTTPS トンネル
クライアントは、プロキシを通じてポート 443 の example.com への TLS トンネルを要求します。プロキシは Proxy-Authorization ヘッダーを使ってクライアントを認証し、TCP 接続を開き、200 OK で確認します。
リクエスト
CONNECT example.com:443 HTTP/1.1
Host: example.com:443
Proxy-Authorization: Basic dXNlcjpwYXNz
レスポンス
HTTP/1.1 200 Connection Established
200 レスポンスを受け取ったあと、クライアントは開かれたトンネルを通じて example.com との TLS ハンドシェイクを開始します。プロキシは以降のすべてのデータを、内容を検査も変更もせずに転送します。
認証なしのトンネル
プロキシが資格情報を要求しない場合、リクエストにはターゲットのホストとポートのみが含まれます。
リクエスト
CONNECT example.com:443 HTTP/1.1
Host: example.com:443
レスポンス
HTTP/1.1 200 Connection Established
CORS
CONNECT は CORS の禁止メソッドです。ブラウザは fetch() や XMLHttpRequest などのブラウザ API を通じて CONNECT を送信しようとするあらゆる試みをブロックします。
HTTP トンネリング
HTTP トンネリングは HTTP 以外のトラフィックを HTTP メッセージ内にカプセル化し、HTTPS、SSH、FTP といったプロトコルが HTTP プロキシを通過できるようにします。CONNECT はこうしたトンネルを確立するための主要な仕組みです。プロキシはターゲットのホストとポートへの生の TCP 接続を開き、内容を検査せずにバイト列を双方向に中継します。
クライアントとサーバーのあいだにプロキシがなければ、CONNECT は不要です。クライアントはターゲットのプロトコルを使ってサーバーに直接接続します。
セキュリティ
任意のポートへの CONNECT を受け付けるオープンプロキシは悪用を招きます。SMTP(ポート 25)経由のスパム中継、内部ネットワークのポートスキャン、ネットワークアクセス制御の回避などです。本番環境のプロキシは CONNECT をポート 443(HTTPS)または承認済み宛先のホワイトリストに制限します。
OWASP は無制限の CONNECT をセキュリティリスクとして認識しています。WHATWG Fetch Standard は CONNECT を禁止メソッドに分類しており、ブラウザが fetch() や XMLHttpRequest を通じて直接 CONNECT リクエストを送信することを防いでいます。