20190502 追記
動いた
20180922 追記
RFC8470として標準化されました
無事Too Earlyのステータスコードが 425になりました (URL)
本記事は、draft-00時点の記述の通り、未定を示す4NNのままとしておきます。
2020/01/19追記
#http_tokyo で詳しい説明をしました。あわせてどうぞ
TLS1.3では、0-RTTハンドシェイクの際にearly_dataとしてアプリケーションデータを送信できます。しかし、この0-RTTハンドシェイクで送信するデータには、リプレイ攻撃のリスクがあります。
そのリスクをさけるための機能をHTTPに追加する提案が出ています。
提案仕様は、「Using TLS Early Data in HTTP」で公開されており、著者はMartin Thomson, Mark Nottinghamらである。
この仕様ではHTTPに以下の機能を追加します
背景
現在標準化の大詰めを迎えているTLS1.3の機能の一つに 0-RTT Data というものがります。
これは、一度TLSハンドシェイクを行ったサーバに対して再度ハンドシェイクを行う際は、ClientHelloと共にアプリケーションデータも送信する手順です。通常のフルハンドシェイク手順よりも早くアプリケーションデータを送信し始めることができます。パケットの往復を待たずに送りたいデータを送ることから、0-RTTハンドシェイクとも呼ばれます。
具体的な手順は、TLS1.3の仕様の2.3節で示されています
この0-RTTハンドシェイクで送信されるアプリケーションデータはもちろん暗号化されていますが、リプレイ攻撃が可能です。0-RTTハンドシェイクのClientHelloのパケットを観測し、再度サーバに送りつけ多重にリクエストを処理させることができます。
そのため、この0-RTTハンドシェイクで送信するアプリケーションデータはべき等なもの、つまり、なんど処理をしても結果が変わらないものに限られるべきです。HTTPで言えばGETメソッドなどがそう言えるでしょう(そうでないものも多いですが)。
4NN (Too Early)と、Early-Dataヘッダ
この 0-RTT Dataのリスクを軽減するために「Using TLS Early Data in HTTP」という提案がでています。この仕様ではHTTPに以下の機能を追加します
4NN (Too Early)
4NN (Too Early)は、サーバがリプレイ攻撃の危険性がある0-RTTハンドシェイクのearly_dataデータを処理したくないことをクライアントに通知するステータスコードです。
このステータスコードを受け取ったクライアント(User-Agentやプロキシ)は自動でリクエストを再試行すべきではありません、全く新しいコネクションとしてサーバに接続する必要があります。
418 VS その他
具体的なステータス番号については、Author間で議論がありました。まだIANAに登録されていない418を使うという提案がありましたが、Hyper Text Coffee Pot Control Protocolで「418 I'm a teapot」として使用されています。
「418 I'm a teapot」は https://www.google.com/teapot 実際にデプロイされておりますが、HTCPCPはジョークRFCであり、HTTPとは別のプロトコルであるためステタース番号はかぶっても良いという意見です。
また、ジョークRFCによって貴重な番号が消費される事についても意見がついているようです。
しかし最終的には関係者と議論して決めるようです。
Early-Dataヘッダ
TLSを終端するサーバとアプリケーションサーバが別れている構成は一般的です。もちろんCDNやクラウドサービスのTLS終端サービスはそのHTTPリクエストがリプレイ攻撃されても問題ないか判断はできません。
そのため、TLS終端したサーバはそれが元々0-RTTハンドシェイクで送られてきたデータなのか区別できるようにする必要があります。
仕様では、HTTPリクエストが0-RTTearly_dataで送信されていることを示すEarly-Dataヘッダが定義されています。0もしくは1であり、1がearly_dataで送信されていることを示します。
TLSを終端しているサーバがEarly-Dataヘッダを付与します。"Early-Data"ヘッダーフィールドは、ユーザーエージェント(つまり最初のリクエストを送った者)が使用するためのものではありません。
この時、4NNを受け取った場合の終端サーバはクライアントにそれを転送しなければなりません。
またEarly-Dataヘッダは、4NNステータスコードを理解できることも示しています。