インターネットエンジニアリングタスクフォース (IETF) M. Nottingham
Request for Comments: 9205 2022年6月
廃止: 3205
BCP: 56
カテゴリ: 最良の現行慣行
ISSN: 2070-1721

HTTPによるプロトコルの構築


概要

アプリケーションはしばしばHTTPを基盤としてHTTPベースのAPIを作成します。本書は、HTTPを用いて新しいアプリケーションプロトコルを定義する仕様を作成する際のベストプラクティスを規定します。主にインターネット上での展開のためにHTTPを利用するアプリケーションプロトコルを定義するIETFの取り組みを導くことを目的として作成されていますが、他の状況でも適用可能です。

本書はRFC 3205を廃止します。

このメモの状態

このメモはインターネットの最良現行慣行を文書化したものです。

本書はインターネットエンジニアリングタスクフォース (IETF) の成果物です。IETFコミュニティの合意を表しています。公開審査を経てインターネットエンジニアリング運営グループ (IESG) による公開承認を受けています。BCPに関する詳細は RFC 7841 のセクション 2 を参照してください。

本書の現状、訂正情報 (errata)、およびフィードバックの送付方法に関する情報は https://www.rfc-editor.org/info/rfc9205 で入手できます。

Copyright Notice

Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.


1. 導入

Webブラウジング以外のアプリケーションはしばしばHTTP [HTTP] を基盤として使用します。この慣行は「HTTPベースのAPI」「REST API」あるいは単に「HTTP API」と呼ばれることがあります。これが行われる理由には以下のようなものがあります:

  • 実装者、仕様作成者、管理者、開発者、および利用者にとっての馴染みやすさ;
  • さまざまなクライアント、サーバー、およびプロキシ実装の利用可能性;
  • 使いやすさ;
  • Webブラウザの利用可能性;
  • 認証や暗号化といった既存の仕組みの再利用;
  • 対象デプロイメントにおけるHTTPサーバーやクライアントの存在;
  • ファイアウォールを通過できる能力。

これらのプロトコルはしばしば場当たり的で、1つまたは少数のサーバーによるデプロイと限られたクライアント群による利用のみを想定しています。その結果、こうした条件を好むHTTPベースのAPIの定義に関する実践とツール群が生じています。

しかし、そのようなアプリケーションが複数の独立した実装を持ち、複数の調整されていないサーバーにデプロイされ、多様なクライアントに消費される場合(標準化努力によって定義されるHTTP APIにしばしば見られるように)、限定的なデプロイ向けのツールや実践は不適切になることがあります。

この不一致は主に、APIのクライアントとサーバーが異なる速度で実装および進化するため、異なる機能やバージョンを持つデプロイメントが共存する必要が生じることに起因します。その結果、そのようなデプロイメントを想定したHTTPベースのAPIの設計者は、サービスの拡張性をどのように扱うか、異なるデプロイ要件をどのように受け入れるかをより慎重に検討する必要があります。

より一般的には、HTTPを使用するアプリケーションプロトコルは多数の設計判断に直面します。これには例えば次のようなものがあります:

  • 新しいURIスキームを定義すべきか?新しいポートを使うべきか?
  • 標準のHTTPメソッドやステータスコードを使うべきか、それとも新しいものを定義するべきか?
  • HTTPの利用から最大の価値をどう引き出すか?
  • 特にWebブラウジングとの共存をどのように実現するか?
  • 相互運用性の問題や「プロトコルの行き止まり」をどう回避するか?

セクション 2は本書が適用される場合を定義し、セクション 3は保持すべきHTTPの特性を概観し、セクション 4にはHTTPを使用するアプリケーションの仕様作成に関するベストプラクティスが含まれます。

本書は主にインターネット上での展開を目的としてHTTPを用いるアプリケーションプロトコルを定義するIETFの取り組みを導くために書かれていますが、他の状況にも適用可能です。ここに記載された要件は必ずしも汎用のHTTP拡張の開発に適用されるわけではないことに注意してください。

本書は [RFC3205] を廃止し、HTTPに関する経過時間中の経験と発展を反映しています。

1.1. 表記規約

本書におけるキーワード "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", および "OPTIONAL" は、すべて大文字で示される場合に限り BCP 14 に記載されたとおりに解釈されます。[RFC2119] [RFC8174] を参照してください。


2. HTTPは使用されていますか?

HTTPを使用する目的はアプリケーションごとに異なります。本書の推奨事項は、仕様が次の条件を満たすアプリケーションを定義する場合に適用されます:

  • トランスポートポートとして80または443を使用する、または
  • URIスキーム "http" または "https" を使用する、または
  • ALPNプロトコルID [RFC7301] を使用して一般的にHTTPを識別する(例: "http/1.1", "h2", "h3")、または
  • HTTP用に定義されたIANAレジストリへの登録または全体的な変更を行う。

さらに、仕様がHTTPを使用する場合、HTTPプロトコルスイートのすべての要件が適用されます(特に [HTTP] ですが、使用する特定のHTTPのバージョンや利用する拡張も含まれます)。

本書はアプリケーションに適用されることを意図しており、汎用のHTTP拡張には当てはまらないことに注意してください。さらに、本書は主にIETFで仕様化されるアプリケーションを対象としますが、他の標準化団体もその要件に従うことが奨励されます。

2.1. 非HTTPプロトコル

アプリケーションは、上記のHTTP使用基準を満たさなくてもHTTPに依存することができます。たとえば、メッセージ形式の一部を再定義したくないがプロトコルの他の動作を変更したい場合や、アプリケーション固有のメソッドを使用したい場合があります。

そうすることでプロトコル動作をより自由に変更できますが、セクション 3で概説されている利点の少なくとも一部が失われます。大多数のHTTP実装はこれらの変更に容易に適応できないためです。マインドシェア(広く認知されていること)の利点も失われます。

そのような仕様は MUST NOT HTTPのURIスキーム、トランスポートポート、ALPNプロトコルID、またはIANAレジストリを使用してはなりません。代わりに、それら自身のものを定義することが推奨されます。


3. HTTPの重要な点

このセクションでは、アプリケーションプロトコルを定義する際に考慮すべき、HTTPの重要な特性を検討します。

3.1. 汎用セマンティクス

HTTPの価値の多くはその汎用的なセマンティクスにあります。つまり、HTTPによって定義されるプロトコル要素は、特定の文脈に限定されず、あらゆるリソースに適用可能であるという点です。アプリケーション固有のセマンティクスは、ステータスコードやメソッドではなく、メッセージコンテンツやヘッダーフィールドで表現するのが適切です(とはいえ、ステータスコードやメソッドにもアプリケーション状態に関連する汎用的セマンティクスはあります)。

この汎用とアプリケーション固有のセマンティクスの分離により、HTTPメッセージは共通のソフトウェア(例: HTTPサーバー、中間機、クライアント実装、キャッシュ)によってアプリケーションを理解することなく処理され得ます。また、特定のアプリケーションについての専門知識がなくてもHTTPのセマンティクスの知識を活用できるようになります。

したがって、HTTPを使用するアプリケーションは、メソッド、ステータスコード、既存のヘッダーフィールドなどの汎用的なプロトコル要素のセマンティクスを再定義、細分化、上書きしてはなりません(MUST NOT)。代わりに、仕様はそのアプリケーション固有のプロトコル要素、すなわちHTTPリソースに焦点を当てるべきです。

仕様を書く際には、HTTPがどのように実装、サポート、使用されるべきかを正確に指定したくなることがよくあります。しかし、これにより意図しないHTTP動作のプロファイルが生まれることがあります。例えば、次のような文言を含む仕様をよく見かけます:

POSTリクエストは必ず201 (Created) の応答を返さなければならない。

このような記述は、実際のデプロイメントではステータスコードが異なる理由が多数あるにもかかわらず、クライアントに対して常に201が返るという期待を生じさせます。例えば、認証を要求するプロキシがある場合や、サーバー側のエラー、リダイレクションなどが考えられます。クライアントがこれらを想定していないと、アプリケーションのデプロイメントは脆弱になります。

詳細は セクション 4.2 を参照してください。

3.3. 豊富な機能

HTTPはアプリケーションに対して次のような多数の機能を提供します:

  • メッセージのフレーミング
  • 多重化(HTTP/2 [HTTP/2] および HTTP/3 [HTTP/3] において)
  • TLSとの統合
  • 中間体(プロキシ、ゲートウェイ、コンテンツ配信ネットワーク(CDN))のサポート
  • クライアント認証
  • フォーマット、言語、その他の機能に対するコンテンツネゴシエーション
  • サーバーのスケーラビリティ、レイテンシおよび帯域幅の削減、信頼性のためのキャッシング
  • URL空間の豊かな利用によるアクセス制御の粒度
  • レスポンスの一部を選択的に要求するための部分コンテンツ
  • Webブラウザを用いてアプリケーションと容易に対話できる能力

HTTPを使用するアプリケーションは、これらの機能を活用して、ユーザーがそれらの恩恵を最大限に受けられるようにし、さまざまな状況でデプロイできるようにすることが奨励されます。本書は特定の機能の使用を義務付けるものではありません。適切な設計上のトレードオフは状況に強く依存するためです。しかし、セクション 4の実践に従うことが良い出発点となります。


4. HTTPの使用を指定する際のベストプラクティス

このセクションには、特定のHTTPプロトコル要素に関する実践を含め、アプリケーションがHTTPを使用する際の仕様作成に関するベストプラクティスが含まれます。

4.1. HTTPの使用の指定

仕様はHTTPの主要な参照として[HTTP]を使用すべきです; 特定の機能が明示的に指定されているなどの特別な理由がない限り、HTTPスイート内のすべての仕様を参照する必要はありません。

HTTPはホップバイホップのプロトコルであるため、接続はアプリケーションが制御していない実装(プロキシ、CDN、ファイアウォールなど)によって扱われる可能性があります。特定のHTTPバージョンを必須とするとこれらの状況での利用が困難になり、相互運用性を損ないます。したがって、HTTPを使用するアプリケーションが使用するHTTPの最低バージョンを指定することは推奨されません

ただし、アプリケーションのデプロイメントが特定のHTTPバージョン(例えばHTTP/2の多重化)を利用することで利益を得る場合は、その旨を記述すべきです。

HTTPを使用するアプリケーションは、プロトコルの進化能力を保持するために、最大バージョンを指定してはなりません (MUST NOT )。

プロトコル相互作用の例を指定する際、アプリケーションはリクエストとレスポンスの両方のメッセージを完全なヘッダセクションで文書化するべきで、望ましくはHTTP/1.1形式で示すべきです [HTTP/1.1]。例えば:

GET /thing HTTP/1.1
Host: example.com
Accept: application/things+json
User-Agent: Foo/1.0

HTTP/1.1 200 OK
Content-Type: application/things+json
Content-Length: 500
Server: Bar/2.2

[content here]

4.2. サーバーの動作の指定

アプリケーションのサーバー側の動作は、以下のプロトコル要素を定義することで最も効果的に指定されます:

  • メディアタイプ [RFC6838]、しばしばJSONのようなフォーマット慣習に基づく;
  • HTTPヘッダフィールド(セクション 4.7参照); および
  • リンク関係によって識別されるリソースの動作 [WEB-LINKING]

これらのプロトコル要素を組み合わせて、リンク関係で識別され指定された動作を実装する一連のリソースを定義することで、アプリケーションの動作を定義できます。これには例えば:

  • GETを使用した複数のメディアタイプで識別される形式でのリソース状態の取得;
  • POSTまたはPUTを使用したリソースの作成または更新(適切に識別されたリクエストコンテンツ形式で);
  • POSTを用いたデータ処理(識別されたリクエストおよびレスポンスのコンテンツ形式を使用); および
  • DELETEを使用したリソースの削除。

例えば、アプリケーションは次のように指定するかもしれません:

"example-widget"リンク関係タイプでリンクされたリソースはWidgetです。Widgetの状態は"application/example-widget+json"形式で取得でき、同じリンクへPUTすることで更新できます。Widgetリソースは削除できます。

Widget表現のExample-Countレスポンスヘッダフィールドは、送信者が保持するWidgetの数を示します。

"application/example-widget+json"形式は、Widgetの状態を表すJSON [RFC8259]形式です。Linkヘッダフィールドの値に示されたリンクで"example-other-info"リンク関係タイプにある関連情報へのリンクを含みます。

アプリケーションはURIテンプレート [URI-TEMPLATE] の使用を指定して、クライアントがランタイムデータに基づいてURLを生成できるようにすることもできます。

4.3. クライアントの動作の指定

アプリケーションがクライアントに期待する動作は、相互運用性の問題を避けるためにWebブラウザの期待と密接に整合しているべきです。

その一つの方法は、ブラウザがHTTPに対して使用する抽象である[FETCH]に基づいて定義することです。

自動リダイレクト処理などのいくつかのクライアント挙動やクッキーのような拡張は、HTTPによって必須ではありませんが非常に一般的になっています。アプリケーションがそれらの使用を明示的に指定しない場合、混乱や相互運用性の問題が生じる可能性があります。特に次の点に注意してください:

リダイレクト処理:
アプリケーションはリダイレクトをどのように扱うことを期待するかを指定する必要があります。詳細はセクション 4.6.1を参照してください。
クッキー:
HTTPを使用するアプリケーションは、クッキーが必要な場合はクッキー仕様 [COOKIES] を明示的に参照するべきです。
証明書:
HTTPを使用するアプリケーションは、HTTPSが使用される場合にTLS証明書がSection 4.3.4 に従って検証されることを指定するべきです。

HTTPを使用するアプリケーションは、通常ネゴシエートされるHTTP機能をクライアントが静的にサポートすることを要求すべきではありません。例えば、あるコンテンツコーディングをクライアントが静的にサポートすることを要求する([HTTP]Section 8.4.1)代わりに、それをネゴシエートする([HTTP]Section 12.5.3)べきです。前者は、そうでなければ適合するクライアントがアプリケーションと相互運用できなくなることを意味します。とはいえ、アプリケーションはそのような機能の実装を奨励することはできます。

4.4. URLの指定

HTTPでは、クライアントがやり取りするリソースはURLで識別されます [URL][BCP190] が説明するように、URLの一部はサーバーの所有者("authority")の制御下に置かれるよう設計されており、これがデプロイの柔軟性を与えます。

これは多くの場合、HTTPを使用するアプリケーションの仕様が固定されたアプリケーションURLやパスを含まないことを意味します。単一デプロイ向けAPIの仕様で"/app/v1"のようなパスプレフィックスを指定するのは一般的ですが、IETFの仕様でそれを行うのは不適切です。

したがって、仕様作成者はクライアントがアプリケーションのURLを発見する手段を提供する必要があります。加えて、どのURLスキームを使用するか、専用ポートを用いるかHTTPのポートを再利用するかを指定する必要があります。

4.4.1. アプリケーションのURLの検出

一般に、クライアントは特定のデプロイメントに関する情報(他の関連リソースへのリンクを含むことがある)を含む初期ドキュメントを要求することで、そのアプリケーションサーバーとのやり取りを開始します。これによりデプロイは可能な限り柔軟になり(複数サーバーにまたがる可能性など)、進化を許容し、また"ディスカバリドキュメント"をクライアントに合わせて調整する機会を与えます。

初期URLを検出するための一般的なパターンがいくつかあります。

最も直接的なURL検出メカニズムは、クライアントを完全なURLで設定する(またはそれを伝える)ことです。これは設定ドキュメントや他のディスカバリメカニズムを通じて行われるかもしれません。

しかし、クライアントがサーバーのホスト名とアプリケーションの識別子しか知らない場合、そこから初期URLを導出する方法が必要になります。

アプリケーションはURLパスの固定プレフィックスを定義できません; 詳細は[BCP190]を参照してください。代わりに、そのようなアプリケーションの仕様は次の戦略のいずれかを使用できます:

  • そのアプリケーションのエントリポイントとしてwell-known URI [WELL-KNOWN-URI] を登録する。これにより、他のアプリケーションと衝突しない固定パスが各サーバーに提供されます。
  • サーバー権限がエントリポイントのURLを生成するためのURIテンプレート [URI-TEMPLATE] や類似のメカニズムを伝達できるようにする。例えば、これは設定ドキュメントや他のアーティファクトで行われるかもしれません。

一度ディスカバリドキュメントが見つかれば、それを取得し(メタデータが許す場合は)後で再利用のためにキャッシュし、完全なURIやURLテンプレートを使ってアプリケーションに関連する他のリソースを見つけるために使用できます。

場合によっては、通信が非常に短い場合やレイテンシの懸念からディスカバリドキュメントの使用を避けたい場合があります。これらの状況には、アプリケーションのすべてのリソースをwell-knownな場所に配置することで対処できます。

4.4.2. URIスキームの検討

HTTPを使用するアプリケーションは通常 "http" および/または "https" URIスキームを利用します。認証、完全性、機密性を提供し、広範な監視攻撃を軽減するために "https" が推奨されます [RFC7258]

ただし、アプリケーション固有のスキームを定義することも可能です。HTTPを使うアプリケーションのURIスキームを定義する際には、いくつかのトレードオフと注意点があります:

  • 未修正のWebブラウザは新しいスキームをサポートしません。Webブラウザに新しいURIスキームを登録することは可能ですが(例: [HTML] の registerProtocolHandler() など)、これらのメカニズムのサポートはブラウザ間で一貫しておらず、機能も異なります。
  • 既存の非ブラウザクライアント、中間体、サーバー、および関連ソフトウェアは新しいスキームを認識しません。例えば、クライアントライブラリがリクエストを適切に送信できなかったり、キャッシュがレスポンスの保存を拒否したり、プロキシがリクエストを転送できなかったりする可能性があります。
  • URLはHTTPアーティファクトに自動生成されることが多いため(例: Locationレスポンスヘッダフィールド)、新しいスキームが一貫して使用されるようにするのは難しいことがあります。
  • 新しいスキームで識別されるリソースは依然として "http" および/または "https" URLで利用可能です。それらのURLが使用されてしまうと、セキュリティや運用上の問題が発生する可能性があります。例えば、リクエストが通常のWebサイトに送信されないように新しいスキームを使おうとするのは失敗しやすいです。
  • Webの同一生成元ポリシーのようにURLのオリジンに依存する機能は、スキームの変更によって影響を受けます [RFC6454]
  • クッキー [COOKIES]、認証 [HTTP]、キャッシュ [HTTP-CACHING]、HTTP Strict Transport Security (HSTS) [RFC6797]、Cross-Origin Resource Sharing (CORS) [FETCH] のようなHTTP固有の機能は、定義と実装に依存して正しく動作しないことがあります。一般にこれらはURLが常に "http" または "https" であることを前提に設計されています。
  • セキュアコンテキストを要求するWeb機能 [SECCTXT] は、新しいスキームを安全でないものとして扱う可能性があります。

新しいURIスキームの作成に関する詳細は [RFC7595] を参照してください。

4.4.3. トランスポートポートの選択

アプリケーションはデフォルトのポート(HTTPは80、HTTPSは443)を使用するか、他のポートでデプロイすることができます。この決定はデプロイ時に行うか、仕様で推奨することができます(例: そのアプリケーションのためにポートを割り当て登録するなど)。

非デフォルトポートを使用する場合、そのポートはすべてのリソースのURLのauthorityに反映される必要があります; デフォルトポートを変更する唯一のメカニズムはURIスキームを変更することです(セクション 4.4.2参照)。

デフォルト以外のポートを使用するとプライバシーへの影響(つまり、プロトコルが他のトラフィックと区別されるようになる)や運用上の懸念(いくつかのネットワークがブロックする可能性がある)が生じます。これらのプライバシーの影響(区別可能性から生じるものを含む)はセキュリティ考慮事項に文書化されるべきです。

さらなるガイダンスについては [RFC7605] を参照してください。

4.5. HTTPメソッドの使用

HTTPを使用するアプリケーションは、GET、POST、PUT、DELETE、PATCHのような登録済みのHTTPメソッドの使用に限定しなければなりません (MUST)。

新しいHTTPメソッドはまれであり、IETFレビューでの登録が必要です("HTTP Method Registry")。また、それらは汎用である必要があります。つまり、特定のアプリケーションのリソースだけでなく、潜在的にすべてのリソースに適用可能でなければなりません。

歴史的に一部のアプリケーション(例: [RFC4791])はアプリケーション固有のメソッドを定義してきましたが、[HTTP] は現在これを禁止しています。

新しいメソッドが必要だと著者が考える場合は、早期にHTTPコミュニティ(例: <mailto:ietf-http-wg@w3.org> メーリングリスト)と関わり、アプリケーション仕様の一部としてではなく別個のHTTP拡張として提案を文書化することが推奨されます。

4.5.1. GET

GETは最も一般的で有用なHTTPメソッドであり、その取得セマンティクスはキャッシュや副作用のないリンク付けを可能にし、HTTPを使用する多くの利点の基礎となります。

クエリはしばしばURLのクエリコンポーネントを使用してGETで行われます。これはWebブラウジングで馴染みのあるパターンであり、結果はキャッシュされ、高コストの処理の効率を改善できます。しかし、バイナリデータがクエリの一部である場合など、URIの制限された構文のためにGETが扱いにくくなることがあります。

短いクエリでは問題になりませんが、大きなクエリや高頻度のリクエストが必要な場合には問題になることがあります。さらに、一部のHTTP実装はサポートするURLのサイズを制限していますが、現代のHTTPソフトウェアは以前よりもはるかに寛大な限界を持っています(通常、[HTTP] が要求するように8000オクテットよりかなり多い)。

これらの場合、HTTPを使用するアプリケーションはクエリをリクエストのコンテンツで表現するためにPOSTの使用を検討してもよいです; これによりエンコードのオーバーヘッドや実装におけるURL長制限を回避できます。ただし、その場合GETのキャッシュやクエリ結果へのリンクといった利点は失われます。したがって、POSTクエリをサポートする必要があるアプリケーションは両方のメソッドを許容することを検討すべきです。

GETリクエストの処理はアプリケーションの状態を変更したり、クライアントにとって重要な副作用を持ってはなりません。なぜなら実装は失敗したHTTP GETリクエストを再試行することがあり、またTLSのearly dataで保護された一部のGETリクエストはリプレイ攻撃に対して脆弱である可能性があるためです([RFC8470]参照)。これはログ記録などの類似機能を含みません; 詳細は [HTTP]Section 9.2.1 を参照してください。

最後に、汎用のHTTP構文ではGETリクエストメッセージにコンテンツを含めることが許されていますが、これはメッセージパーサーを汎用にするためのものです。[HTTP]Section 9.3.1 によれば、GETの中のコンテンツは推奨されず意味を持たず、汎用のHTTPソフトウェア(中間体、キャッシュ、サーバー、クライアントライブラリなど)によって無視または拒否されます。

4.5.2. OPTIONS

OPTIONSメソッドはメタデータ取得のために定義され、WebDAV [RFC4918] やCORS [FETCH] で使用されます。HTTPベースのAPIはしばしばリソースに関するメタデータを取得する必要があるため、OPTIONSが検討されます。

しかし、OPTIONSには重要な制限があります:

  • OPTIONSはデフォルトメソッドではないため、単純なURLでメタデータにリンクすることができません。
  • OPTIONSレスポンスはキャッシュ可能ではありません。HTTPキャッシュはリソースの表現(つまりGETとHEAD)に基づいて動作するためです。OPTIONSレスポンスを別個にキャッシュする場合、そのHTTPキャッシュの有効期限、二次キー、その他のメカニズムとの相互作用を考慮する必要があります。
  • OPTIONSは"チャッティ"です — メタデータを別途要求することで、アプリケーションとのやり取りに必要なリクエスト数が増えます。
  • OPTIONSの実装サポートは普遍的ではありません; 一部のサーバーは大きな労力なしにOPTIONS要求に応答する機能を公開しないことがあります。

OPTIONSの代わりに次のいずれかの代替アプローチがより適切かもしれません:

  • サーバー全体のメタデータについては、well-known URI [WELL-KNOWN-URI] を作成するか、適切であれば既存のものを使用する(例: host-meta [RFC6415])。
  • 特定のリソースに関するメタデータについては、別個のリソースを作成し、それへのリンクをLinkレスポンスヘッダフィールドやレスポンス内容に直列化されたリンクで示す。[WEB-LINKING] を参照。LinkヘッダフィールドはHEADレスポンスでも利用可能であり、クライアントがリソースと対話する前にその機能を発見したい場合に有用です。

4.6. HTTPステータスコードの使用

HTTPステータスコードはキャッシュや中間体、クライアントなどの汎用HTTPコンポーネントおよびアプリケーション自体の利便のためにセマンティクスを伝えます。しかし、アプリケーションはその使用においていくつかの落とし穴に直面します。

まず、ステータスコードはしばしばアプリケーション以外のコンポーネントによって生成されます。例えば、ネットワークエラーが発生した場合、キャプティブポータルやプロキシ、CDNが存在する場合、またはサーバーが過負荷状態にある、あるいは攻撃を受けていると考える場合などです。特定のエラー条件が発生したときに汎用クライアントソフトウェアがステータスコードを生成することさえあります。その結果、アプリケーションが特定のステータスコードに特定のセマンティクスを割り当てると、クライアントはそのステータスコードがアプリケーションではなく汎用コンポーネントによって生成されたために状態を誤認する可能性があります。

さらに、アプリケーションのエラーを個別のHTTPステータスコードに1対1でマッピングすると、適用可能なHTTPステータスコードの有限の空間が枯渇する状況に陥りやすいです。これにより、新しいアプリケーション固有のステータスコードを作成したり、既存のステータスコードをその意味と乖離して使用したりするなどの悪い慣行につながります。

代わりに、HTTPを使用するアプリケーションは、最も適切なステータスコードを使用し、疑わしい場合は一般的なステータスコード(200、400、500など)を寛大に使うべきです。重要なのは、ステータスコードとアプリケーションエラーの間に1対1の関係を指定しないことであり、これにより前述の枯渇問題を回避できます。

同じステータスコードにマップされた複数のエラー状態を区別し、前述の誤帰属の問題を避けるために、HTTPを使用するアプリケーションはレスポンスのメッセージ内容および/またはヘッダフィールドでより細かいエラー情報を伝えるべきです。[PROBLEM-DETAILS] はその一つの方法を提供します。

登録されたHTTPステータスコードの集合は拡張され得るため、HTTPを使用するアプリケーションはクライアントがすべての適用可能なステータスコードを優雅に扱えるようにすべきであることを明示するべきです(つまり、あるステータスコードを認識しないクライアントはそのコードの一般的なn00のセマンティクスにフォールバックできること; 例えば499を認識しないクライアントは安全に400 (Bad Request) として扱える等)。これは将来的に完全でない洗い出しリストを作成するより好ましいです。

HTTPを使用するアプリケーションはHTTPステータスコードのセマンティクスを再定義してはなりません (MUST NOT)。理由句を特定のものにすることを要求するのは推奨されません; 理由句はHTTPにおいて機能を持たず、実装によって保持される保証がなく、HTTP/2のメッセージ形式ではまったく運ばれません。

アプリケーションは登録済みのHTTPステータスコードのみを使用しなければなりません (MUST)。メソッドと同様に、新しいHTTPステータスコードはまれであり、IETFレビューで登録されることが要求されます。HTTPステータスコードは汎用的であり、特定のアプリケーションのリソースだけでなく潜在的にすべてのリソースに適用可能である必要があります。

著者が新しいステータスコードが必要だと考える場合は、早期にHTTPコミュニティ(例: <mailto:ietf-http-wg@w3.org> メーリングリスト)と関わり、アプリケーション仕様の一部としてではなく別個のHTTP拡張として提案を文書化することが推奨されます。

4.6.1. リダイレクション

3xx系列のステータスコードはSection 15.4で定義され、ユーザエージェントにリクエストを満たす別のリソースを指示します。最も一般的なのは301、302、307、308で、これらはすべてクライアントがリクエストを再送する場所を示すLocationレスポンスヘッダフィールドを使用します。

このグループのメンバーが異なる点は二つあります:

  • 恒久的か一時的か。恒久的リダイレクトはクライアントに保存されたリンク(例: ブックマーク)を更新させるために使用できますが、一時的なものはそうできません。これはHTTPキャッシングには影響しません; 完全に別のものです。
  • リダイレクトがPOSTからGETへのリクエストメソッド変更を許すかどうか。Webブラウザは一般に301および302に対してPOSTをGETに変更するため、308および307はメソッドを変更せずにリダイレクトを許可するために作成されました。

この表はそれらの関係を要約します:

表 1
恒久的 一時的
POSTからGETへのリクエストメソッドの変更を許す 301 302
リクエストメソッドの変更を許さない 308 307

303 (See Other) ステータスコードは、操作の結果がGETを使って別の場所で利用可能であることをクライアントに通知するために使用できます。

[HTTP] に記載されているように、ユーザエージェントは特定のステータスコードのセマンティクスを理解していなくてもLocationレスポンスヘッダフィールドを持つ3xxリダイレクトを自動的に追従してもよいとされています。しかし、それを行う義務はありません; したがって、HTTPを使用するアプリケーションがリダイレクトを自動的に追従させたい場合は、その要件の状況を明示的に指定する必要があります。

リダイレクトは(適切なキャッシュディレクティブがある場合)キャッシュ可能ですが、それ以外では"スティッキー"ではありません。つまり、URIのリダイレクトがあってもクライアントは類似のURI(例: 異なるクエリパラメータを持つもの)もリダイレクトされるとは仮定しません。

HTTPを使用するアプリケーションは、ブラウザ互換性のために301および302レスポンスがPOSTから(ただし他のメソッドからは)GETに後続のリクエストメソッドを変更することを指定することが奨励されます。一般に、リダイレクトされたリクエストが行われるとき、そのヘッダフィールドは元のリクエストからコピーされます。しかし、送信元(および場合によってはパス)が変わると変更されることがあります(送信されたAuthorizationヘッダやCookieヘッダが変わる等)。アプリケーションは、リダイレクト時に定義する任意のリクエストヘッダフィールドを変更または削除する必要があるかを指定するべきですが、この動作は汎用クライアント(ブラウザなど)がその要件を認識していないため、信頼できるものではありません。

4.7. HTTPヘッダフィールドの指定

アプリケーションはしばしば新しいHTTPヘッダフィールドを定義します。通常、HTTPヘッダフィールドの使用は以下のような状況で適切です:

  • そのフィールドが中間体にとって有用である(中間体はしばしばメッセージコンテンツの解析を避けたい)および/または
  • そのフィールドが汎用のHTTPソフトウェア(クライアント、サーバーなど)にとって有用である、および/または
  • 値をメッセージコンテンツに含めることが不可能である(通常はフォーマットがそれを許さないため)。

上記の条件が満たされない場合、アプリケーション固有の情報は通常メッセージ内容やURLクエリ文字列など他の場所で伝える方が良いです。

新しいヘッダフィールドは登録されなければなりません (Section 16.3 に従って) 。

新しいヘッダフィールドを作成する際に検討すべきガイドラインは Section 16.3.2 を参照してください。[STRUCTURED-FIELDS] は新しいヘッダフィールドに共通の構造を提供し、その解析と処理における多くの問題を回避します; 新しいヘッダフィールドでの使用が推奨されます

ヘッダフィールド名は短くすることが推奨されます(フィールド圧縮が使われていてもオーバーヘッドがあるため) が、適切に具体的であるべきです。特に、ヘッダフィールドがアプリケーション固有である場合、ハイフンで区切ったアプリケーション識別子をプレフィックスとして使うことができます。

例えば、"example"アプリケーションが3つのヘッダフィールドを作成する必要がある場合、それらは "example-foo", "example-bar", "example-baz" と呼ばれるかもしれません。主な動機はより一般的なフィールド名の消費を避けることであり、アプリケーションのために名前空間の一部を予約することではない点に注意してください; 関連する考慮事項は [RFC6648] を参照してください。

既存のHTTPヘッダフィールドのセマンティクスは、登録を更新したり(許される場合は)それらに対する拡張を定義したりしない限り再定義してはなりません (MUST NOT)。例えば、アプリケーションがLocationヘッダフィールドに特定の文脈で特別な意味を持たせることはできません。

ヘッダフィールドとHTTPキャッシュの相互作用については セクション 4.9 を参照してください。特に、レスポンスを選択するために使用されるリクエストヘッダフィールド(Section 4.1 に従う)は影響を及ぼすため注意が必要です。

アプリケーション状態を運ぶヘッダフィールド(例: Cookie)に関する考慮事項については セクション 4.10 を参照してください。

4.8. メッセージコンテンツの定義

メッセージ内容の一般的な構文慣例にはJSON [JSON]、XML [XML]、およびCBOR [RFC8949] などがあります。これらの使用に関するベストプラクティスは本書の範囲外です。

アプリケーションは定義する各フォーマットについて個別のメディアタイプを登録すべきです; これによりそれらを一意に識別し、使用のネゴシエーションが可能になります。詳細は [RFC6838] を参照してください。

4.9. HTTPキャッシュの活用

HTTPキャッシュ [HTTP-CACHING] は、アプリケーションでHTTPを使用する主な利点の一つです。これによりスケーラビリティが向上し、レイテンシが削減され、信頼性が向上します。さらに、HTTPキャッシュはブラウザや他のクライアント、ネットワーク上のフォワードおよびリバースプロキシ、CDN、サーバーソフトウェアの一部として容易に利用できます。

HTTPを使用するアプリケーションがキャッシュの利点を活用するよう設計されていない場合でも、キャッシュがレスポンスをどのように扱うかを考慮して、ネットワーク、サーバー、クライアント、または途中のインフラに差し挟まれた場合でも正しい動作が保たれるようにする必要があります。

4.9.1. 鮮度

短い鮮度寿命(例えば5秒)の割り当てでも([HTTP-CACHING]Section 4.2)、レスポンスを複数のクライアントや同一クライアントからの繰り返しの同一リクエストに再利用することができます。一般に、何かを安全に再利用できるのであれば、鮮度寿命の割り当てを検討してください。

鮮度を指定する最も一般的な方法はmax-ageレスポンスディレクティブ([HTTP-CACHING]Section 5.2.2.1)です。Expiresヘッダフィールドも使用できますが、必須ではありません; すべての現代的なキャッシュ実装はCache-Controlヘッダフィールドをサポートしており、デルタで鮮度を指定する方が通常より便利でエラーが少ないです。

ほとんどのレスポンスをキャッシュするためにpublicレスポンスディレクティブを追加する必要はありません; これは認証されたレスポンスを保存したい場合、またはキャッシュがステータスコードを理解しておらず明示的な鮮度情報がない場合にのみ必要です。

場合によっては、明示的なキャッシュ鮮度ディレクティブがないレスポンスがヒューリスティックな鮮度寿命を用いて保存・提供されることがあります; 詳細は [HTTP-CACHING]Section 4.2.2 を参照してください。ヒューリスティックはアプリケーションの制御外であるため、明示的な鮮度寿命を設定するか、レスポンスを明示的にキャッシュ不可にする方が一般的に好ましいです。

レスポンスのキャッシュが望ましくない場合、適切なキャッシュレスポンスディレクティブはno-storeです。他のディレクティブは必要なく、no-storeはレスポンスがキャッシュされる可能性がある状況でのみ送信する必要があります。no-cacheディレクティブはレスポンスの保存を許すが、検証なしにキャッシュが再利用することを許さない点に注意してください(名前に反してキャッシュを防ぐわけではありません)。

例えば、このレスポンスはキャッシュによって保存または再利用されません:

HTTP/1.1 200 OK
Content-Type: application/example+xml
Cache-Control: no-store

[content]

4.9.2. 古い応答

著者は、Cache-Control: max-age=0 のような古いレスポンスがオリジンから切断されたときにキャッシュによって再利用され得ることを理解しておくべきです; これはネットワークの問題に対処するのに有用です。

もしこれが特定のレスポンスに適さない場合、オリジンはmust-revalidateキャッシュディレクティブを送るべきです。詳細は Section 4.2.4 と、古いコンテンツに対する追加制御については [RFC5861] を参照してください。

古いレスポンスはバリデータを割り当てることで更新でき、これにより大きなレスポンスの転送帯域幅とレイテンシを節約できます; 詳細は Section 13 を参照してください。

4.9.3. キャッシュとアプリケーションのセマンティクス

アプリケーションが鮮度寿命とは別の寿命を表現する必要がある場合、それはレスポンスの内容または別のヘッダフィールドで別個に伝えられるべきです。この場合、HTTPキャッシュとその寿命との関係を慎重に検討する必要があります。レスポンスは鮮度と見なされている限り使用されるためです。

特に、アプリケーション著者はオリジンから新鮮に取得されていないレスポンスをどのように扱うべきかを考慮する必要があります; 有効期間のような概念がある場合、レスポンスの年齢を考慮してこれを計算する必要があります([HTTP-CACHING]Section 4.2.3参照)。

この問題への対処方法の一つは、使用時にレスポンスが新鮮であることを明示的に指定することです。

4.9.4. リクエストに基づくコンテンツの変化

アプリケーションがリクエストヘッダフィールドを使用してレスポンスのヘッダフィールドやコンテンツを変更する場合、著者はこれがキャッシュに与える影響を指摘すべきです。一般に、そのようなリソースはレスポンスをキャッシュ不可にする(例: [HTTP-CACHING]Section 5.2.2.5 で定義されるno-storeディレクティブ)か、またはそのリソースからのすべてのレスポンス("デフォルト"レスポンスを含む)にVaryレスポンスヘッダフィールドを送る必要があります ([HTTP]Section 12.5.5参照)。

例えば、このレスポンス:

HTTP/1.1 200 OK
Content-Type: application/example+xml
Cache-Control: max-age=60
ETag: "sa0f8wf20fs0f"
Vary: Accept-Encoding

[content]

は、プライベートおよび共有キャッシュの両方で60秒間保存でき、If-None-Matchで再検証可能であり、Accept-Encodingリクエストヘッダフィールドに基づいて変化します。

4.10. アプリケーションの状態の処理

アプリケーションは状態を識別するため、またはリクエストを文脈化するためにクライアント固有データを保存するためにステートフルなクッキー [COOKIES] を使用できます。

使用する場合、クッキーのスコープと使用法を慎重に指定することが重要です; アプリケーションが機密データや機能を公開する(例: 周辺的権限として動作する)場合、悪用の可能性があります。軽減策には、クライアントの意図を保証するためのリクエスト固有のトークンの使用が含まれます。

4.11. 複数リクエストの実行

クライアントはしばしばタスクを実行するために複数のリクエストを送信する必要があります。

HTTP/1 [HTTP/1.1] では、並列リクエストは通常複数の接続を開くことでサポートされます。接続の輻輳制御が調整されないため、同時接続が多すぎるとアプリケーションのパフォーマンスに影響を与える可能性があります。さらに、どの接続をいつ使ってリクエストを発行するかを決定するのが難しい場合があり、これもパフォーマンスに影響します。

HTTP/2 [HTTP/2] および HTTP/3 [HTTP/3] はアプリケーションに多重化を提供し、複数接続を使用する必要性を排除します。しかし、サーバーがレスポンスの優先順位をどのように選ぶかによってアプリケーションのパフォーマンスは依然として大きく影響され得ます。アプリケーションによっては、サーバーがレスポンスの優先度を決定する方が良い場合や、クライアントがサーバーに優先度をヒントとして示す方が良い場合があります(例: [HTTP-PRIORITY])。

すべてのHTTPバージョンにおいて、リクエストは独立して行われます — 二つのリクエストの相対的な順序が処理順序を保証すると期待してはなりません。これらは中間体によって多重化されたり、異なるオリジンサーバーに送られたり、サーバーが異なる順序で処理したりする可能性があるためです。二つのリクエストに厳密な順序が必要な場合、結果を確実にする唯一の信頼できる方法は、最初のリクエストの最終レスポンスが開始されたときに二番目のリクエストを発行することです。

アプリケーションは単一のトランスポート接続上の別々のリクエスト間の関係について仮定してはなりません (MUST NOT)。そうするとHTTPのステートレスプロトコルとしての多くの仮定を壊し、相互運用性、セキュリティ、運用性、進化に問題を引き起こします。

4.12. クライアント認証

アプリケーションはクライアントを識別するためにHTTP認証(Section 11)を使用できます。[RFC7617] によれば、Basic認証スキームはチャネルが安全でない限り(例: "https" URIスキームを使う)機密情報や価値のある情報を保護するのに適していません。同様に [RFC7616] はDigest認証スキームを安全なチャネル上で使用することを要求します。

HTTPSでは、クライアントは証明書を用いて認証されることもあります [RFC8446] が、そのような認証は基盤となるトランスポート接続に本質的にスコープされる点に注意してください。その結果、クライアントは認証された状態がレスポンスの準備に使用されたかどうかを知る方法がありません(ただしVary: * や private キャッシュディレクティブは部分的な指標を与えることがあります)。特に、明示的に未認証のレスポンスを得る唯一の方法は新しい接続を開くことです。

使用する場合、認証のスコープと使用法を慎重に指定することが重要です; アプリケーションが機密データや機能を公開する(例: 周辺的権限として動作する)場合、悪用の可能性があります。軽減策として、クライアントの意図を保証するためのリクエスト固有のトークンの使用が含まれます。

4.13. Webブラウジングとの共存

アプリケーションがWebブラウザで使用される意図がなくても、そのリソースはブラウザや他のHTTPクライアントから引き続きアクセス可能であり続けます。これは、HTTPを使用するすべてのアプリケーションがブラウザとの相互作用、特にセキュリティに関してどのように動作するかを考慮する必要があることを意味します。

例えば、アプリケーションの状態がPOSTリクエストで変更できる場合、Webブラウザは任意のWebサイトからのクロスサイトリクエストフォージェリ(CSRF)を簡単に誘発される可能性があります。

また、攻撃者がアプリケーションのリソースから返されるコンテンツを制御すると(例えば、リクエストの一部がレスポンスに反映される、またはレスポンスに攻撃者が変更できる外部情報が含まれる場合)、ブラウザにコードを注入してオリジンとしてデータや機能にアクセスすることが可能になります。これはクロスサイトスクリプティング(XSS)攻撃として知られています。

これは考慮すべき問題の一部に過ぎません。一般に最良のアプローチは、アプリケーションを実際にWebアプリケーションとして扱い、その安全な開発のためのベストプラクティスに従うことです。

これらのプラクティスの完全な列挙は本書の範囲外ですが、いくつかの考慮事項には次が含まれます:

  • Content-Typeヘッダフィールドでアプリケーション固有のメディアタイプを使用し、クライアントがそれを使用しない場合に失敗するよう要求すること。
  • X-Content-Type-Options: nosniff [FETCH] を使用して、攻撃者に制御されたコンテンツがブラウザによってアクティブコンテンツとして解釈されるのを防ぐこと。
  • Content-Security-Policy [CSP] を使用して、HTMLやPDFのような実行可能なスクリプトを持つアクティブコンテンツの能力を制約し、XSS攻撃を軽減すること。
  • Referrer-Policy [REFERRER-POLICY] を使用して、URL内の機密データがRefererリクエストヘッダフィールドで漏洩するのを防ぐこと。
  • クッキーに 'HttpOnly' フラグを使用して、クッキーがブラウザのスクリプト言語から露出しないようにすること [COOKIES]
  • 認証トークンやパスワードなどの機密情報に対して圧縮を使用することを避けること。ブラウザが提供するスクリプト環境により攻撃者が圧縮領域を繰り返し探査することが可能であり、通信のネットワーク経路に攻撃者がアクセスできる場合、その情報を回復するためにこの機能を悪用され得ます。

それらがどのようにデプロイされることを意図しているかに応じて、HTTPを使用するアプリケーションの仕様はこれらのメカニズムの使用を特定の方法で要求するか、あるいはセキュリティ考慮事項で指摘するだけにとどめるかもしれません。

ブラウザによってアクティブコンテンツとして扱われる意図がないアプリケーションのHTTPレスポンスの例は次のようになります:

HTTP/1.1 200 OK
Content-Type: application/example+json
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'none'
Cache-Control: max-age=3600
Referrer-Policy: no-referrer

[content]

アプリケーションがブラウザ互換性を目標とする場合、クライアントとの対話はブラウザがHTTPに対して使用する抽象である[FETCH]に基づいて定義されるべきです; これにより多くのベストプラクティスが強制されます。

4.14. アプリケーション境界の維持

多くのHTTP機能がオリジンにスコープされるため [RFC6454]、アプリケーションは同じオリジンサーバーを使用する他のアプリケーション(Webブラウジングを含む)とのデプロイがどのように相互作用するかも考慮する必要があります。

例えば、クッキー [COOKIES] がアプリケーション状態を運ぶために使用される場合、それらはデフォルトでオリジンへのすべてのリクエストと共に送信されます(パスでスコープされていない限り)、そしてアプリケーションはオリジン上の他のアプリケーションからのクッキーも受け取る可能性があります。これによりセキュリティ問題やクッキー名の衝突が発生する可能性があります。

これらの問題の一つの解決策は、アプリケーションに専用のホスト名を要求して固有のオリジンを持たせることですが、複数のアプリケーションを単一のホスト名にデプロイできるようにすることが望ましいことが多いです; そうすることで最も多くのデプロイの柔軟性が得られ、それらを"混在"させることができます(詳細は [BCP190] を参照)。

したがって、HTTPを使用するアプリケーションはオリジン上で複数のアプリケーションを許容するよう努めるべきです。具体的には、クッキー、HTTP認証領域 [HTTP]、またはその他のオリジン全体に関わるHTTPメカニズムを指定する際、HTTPを使用するアプリケーションは特定の名前の使用を強制するのではなく、デプロイメント側でそれらを設定できるようにすべきです。部分的にオリジンにスコープする方法を検討し、指定されたメカニズムを用いることを考慮してください。

現代のWebブラウザは一つのオリジンからのコンテンツが別のオリジンのリソースにアクセスする能力を制約してプライベート情報の漏洩を防いでいます。その結果、ブラウザにクロスオリジンデータを公開したいアプリケーションはCORSプロトコルを実装する必要があります; 詳細は [FETCH] を参照してください。

4.15. サーバープッシュの使用

HTTP/2はサーバーがクライアントに対してリクエスト/レスポンス対を"プッシュ"する機能を追加しました [HTTP/2]Section 8.4。サーバープッシュは多くの一般的なアプリケーションセマンティクス(例: "fanout" や publish/subscribe)に適しているように見えますが、いくつかの注意点があります:

  • サーバープッシュはホップバイホップです; つまり中間体によって自動的に転送されません。したがって、プロキシ、リバースプロキシ、CDNと容易に(または全く)動作しない可能性があります。
  • サーバープッシュは誤用された場合にHTTPのパフォーマンスに悪影響を与える可能性があり、特にクライアントが実際に要求したリソースと競合する場合に顕著です。
  • サーバープッシュはキャッシュとの相互作用に関して異なるクライアントで異なる実装があり、機能は様々です。
  • サーバープッシュのAPIは一部の実装で現在利用できず、他の実装では大きく異なります。特にブラウザ向けの現在のAPIはありません。
  • サーバープッシュはHTTP/1.1やHTTP/1.0ではサポートされていません。
  • サーバープッシュはHTTPの"コア"セマンティクスの一部ではないため、将来のバージョンのプロトコルでサポートされない可能性があります。

クライアントが完全なレスポンスを受け取る前に関連する作業を行えるように最適化したいアプリケーション(例えば、その中に含まれる可能性の高いリンクを事前取得する等)は、103 (Early Hints) ステータスコードの使用を検討すると有益かもしれません; [RFC8297] を参照してください。

サーバープッシュを直接使用するアプリケーションは、クロスオリジンプッシュ攻撃を避けるために [HTTP/2]Section 8.4 に記載されている権限に関する要件を順守する必要があります。

4.16. バージョン管理と進化を許容する

アプリケーションプロトコルに新機能を導入したり既存のものを変更したりすることがしばしば必要になります。

HTTPでは、後方互換性のない変更は次のようなメカニズムを用いて行うことができます:

  • 新機能を実装するリソースのURLを識別するために、別個のリンク関係タイプ [WEB-LINKING] を使用すること。
  • 新機能を可能にするフォーマットを識別するために、別個のメディアタイプ [RFC6838] を使用すること。
  • メッセージ内容の外で新機能を実装するために、別個のHTTPヘッダフィールドを使用すること。

5. IANA に関する考慮事項

この文書は IANA に対するアクションを含みません。


6. セキュリティに関する考慮事項

HTTP を使用するアプリケーションは、HTTP 自体および使用する拡張のセキュリティ考慮事項の対象になります。[HTTP][HTTP-CACHING]、および [WEB-LINKING] などがしばしば関連します。

セクション 4.4.2 は "https" URL の利用を推奨し、認証、整合性、機密性を提供し、広範な監視攻撃を軽減するために "http" URL の使用を抑制することを勧めています。多くの HTTP アプリケーションはベアラートークン(例: セッションクッキー)で認証や認可を行います。トランスポートが暗号化されていない場合、HTTP 通信を盗聴または改変できる攻撃者はしばしば権限を昇格させてリソース上の操作を実行できるようになります。

セクション 4.9.3 は、HTTP キャッシュとアプリケーション固有のレスポンス保存やその内部情報との不整合の可能性を強調しています。

セクション 4.10 は、プロトコル内で状態を持つメカニズムを周辺的権限として使用することの影響について議論し、緩和策を示唆しています。

セクション 4.13 は、Web ブラウザの機能が HTTP を使用するアプリケーションに及ぼす影響を強調しています。

セクション 4.14 は、アプリケーションがウェブサイト(および他のアプリケーション)と同じオリジンにデプロイされるときに生じる問題について論じています。

セクション 4.15 は、指定された方法以外で HTTP/2 のサーバープッシュを使用することのリスクを指摘しています。

新しい URI スキームや非標準メソッドのサポートを要求するなど、実装の変更を伴う形で HTTP を使用するアプリケーションは、これらの実装が親の HTTP 実装から「フォーク」されるリスクがあり、その結果として上流で取り入れられるパッチやその他のセキュリティ改善の恩恵を受けられなくなる可能性があります。

6.1. プライバシーに関する考慮事項

HTTP クライアントはサーバーにさまざまな情報を公開する可能性があります。アプリケーションの操作の一部として明示的に送信される情報(例えば名前やユーザー入力データ)や「ワイヤ上」の情報(これが セクション 4.4.2 で "https" が推奨される理由の一つです)に加えて、より明白でない手段によって収集される情報もあり、しばしばユーザーの活動を時間を通じて結び付けることで行われます。

これにはセッション情報、フィンガープリンティングによるクライアントの追跡、コード実行などが含まれます。

セッション情報にはクライアントの IP アドレス、TLS セッションチケット、クッキー、クライアントキャッシュに保存された ETag、およびその他の状態を持つメカニズムが含まれます。アプリケーションは、避けられないか動作に必要でない限りセッションメカニズムの使用を回避することが勧められます。必要な場合は、これらのリスクを文書化する必要があります。使用する場合は、実装がそのような状態をクリアできるようにすることが奨励されます。

フィンガープリンティングは、クライアントのメッセージや振る舞いの固有の側面を利用して異なるリクエストや接続を結び付けます。例えば User-Agent リクエストヘッダは実装に関する特定の情報を伝え、Accept-Language リクエストヘッダはユーザーの優先言語を伝えます。これらのマーカーを組み合わせることでクライアントを一意に識別でき、データに対するコントロールに影響を与え得ます。その結果、アプリケーションはクライアントがリクエストで機能に必要な情報のみを送信するよう指定することが推奨されます。

最後に、アプリケーションがコード実行の機能を公開する場合、環境を観察できる能力はクライアントのフィンガープリンティングや機密データ(セッション情報を含む)の取得・操作の機会として悪用され得るため、細心の注意が必要です。例えば高精度タイマーへのアクセス(間接的であっても)は基盤となるハードウェアのプロファイリングに利用され、システムの一意識別子を作り得ます。可能な限りモバイルコードの使用を避けることが勧められ、避けられない場合はその結果として生じるシステムのセキュリティ特性を注意深く精査する必要があります。

7. 参考文献

7.1. 規範的参照

[BCP190]
Nottingham, M., “URI Design and Ownership”, BCP 190, RFC 8820, DOI 10.17487/RFC8820, June 2020, <https://www.rfc-editor.org/rfc/rfc8820>.
[HTTP]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP Semantics”, STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022, <https://www.rfc-editor.org/info/rfc9110>.
[HTTP-CACHING]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP Caching”, STD 98, RFC 9111, DOI 10.17487/RFC9111, June 2022, <https://www.rfc-editor.org/info/rfc9111>.
[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
[RFC6454]
Barth, A., “The Web Origin Concept”, RFC 6454, DOI 10.17487/RFC6454, December 2011, <https://www.rfc-editor.org/info/rfc6454>.
[RFC6648]
Saint-Andre, P., Crocker, D., and M. Nottingham, “Deprecating the "X-" Prefix and Similar Constructs in Application Protocols”, BCP 178, RFC 6648, DOI 10.17487/RFC6648, June 2012, <https://www.rfc-editor.org/info/rfc6648>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, “Media Type Specifications and Registration Procedures”, BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, <https://www.rfc-editor.org/info/rfc6838>.
[RFC8174]
Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[STRUCTURED-FIELDS]
Nottingham, M. and P-H. Kamp, “Structured Field Values for HTTP”, RFC 8941, DOI 10.17487/RFC8941, February 2021, <https://www.rfc-editor.org/info/rfc8941>.
[URL]
Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax”, STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <https://www.rfc-editor.org/info/rfc3986>.
[WEB-LINKING]
Nottingham, M., “Web Linking”, RFC 8288, DOI 10.17487/RFC8288, October 2017, <https://www.rfc-editor.org/info/rfc8288>.
[WELL-KNOWN-URI]
Nottingham, M., “Well-Known Uniform Resource Identifiers (URIs)”, RFC 8615, DOI 10.17487/RFC8615, May 2019, <https://www.rfc-editor.org/info/rfc8615>.

7.2. 情報的参照

[COOKIES]
Barth, A., “HTTP State Management Mechanism”, RFC 6265, DOI 10.17487/RFC6265, April 2011, <https://www.rfc-editor.org/info/rfc6265>.
[CSP]
West, M., “Content Security Policy Level 3”, W3C Working Draft, June 2021, <https://www.w3.org/TR/2021/WD-CSP3-20210629>.
[FETCH]
WHATWG, “Fetch - Living Standard”, <https://fetch.spec.whatwg.org>.
[HTML]
WHATWG, “HTML - Living Standard”, <https://html.spec.whatwg.org>.
[HTTP-PRIORITY]
一穂, 奥. and L. Pardue, “Extensible Prioritization Scheme for HTTP”, RFC 9218, DOI 10.17487/RFC9218, June 2022, <https://www.rfc-editor.org/info/rfc9218>.
[HTTP/1.1]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP/1.1”, STD 99, RFC 9112, DOI 10.17487/RFC9112, June 2022, <https://www.rfc-editor.org/info/rfc9112>.
[HTTP/2]
Thomson, M., Ed. and C. Benfield, Ed., “HTTP/2”, RFC 9113, DOI 10.17487/RFC9113, June 2022, <https://www.rfc-editor.org/info/rfc9113>.
[HTTP/3]
Bishop, M., Ed., “HTTP/3”, RFC 9114, DOI 10.17487/RFC9114, June 2022, <https://www.rfc-editor.org/info/rfc9114>.
[JSON]
Bray, T., Ed., “The JavaScript Object Notation (JSON) Data Interchange Format”, STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, <https://www.rfc-editor.org/info/rfc8259>.
[PROBLEM-DETAILS]
Nottingham, M. and E. Wilde, “Problem Details for HTTP APIs”, RFC 7807, DOI 10.17487/RFC7807, March 2016, <https://www.rfc-editor.org/info/rfc7807>.
[REFERRER-POLICY]
Eisinger, J. and E. Stark, “Referrer Policy”, W3C Candidate Recommendation CR-referrer-policy-20170126, January 2017, <https://www.w3.org/TR/2017/CR-referrer-policy-20170126>.
[RFC3205]
Moore, K., “On the use of HTTP as a Substrate”, BCP 56, RFC 3205, DOI 10.17487/RFC3205, February 2002, <https://www.rfc-editor.org/info/rfc3205>.
[RFC4791]
Daboo, C., Desruisseaux, B., and L. Dusseault, “Calendaring Extensions to WebDAV (CalDAV)”, RFC 4791, DOI 10.17487/RFC4791, March 2007, <https://www.rfc-editor.org/info/rfc4791>.
[RFC4918]
Dusseault, L., Ed., “HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)”, RFC 4918, DOI 10.17487/RFC4918, June 2007, <https://www.rfc-editor.org/info/rfc4918>.
[RFC5861]
Nottingham, M., “HTTP Cache-Control Extensions for Stale Content”, RFC 5861, DOI 10.17487/RFC5861, May 2010, <https://www.rfc-editor.org/info/rfc5861>.
[RFC6415]
Hammer-Lahav, E., Ed. and B. Cook, “Web Host Metadata”, RFC 6415, DOI 10.17487/RFC6415, October 2011, <https://www.rfc-editor.org/info/rfc6415>.
[RFC6797]
Hodges, J., Jackson, C., and A. Barth, “HTTP Strict Transport Security (HSTS)”, RFC 6797, DOI 10.17487/RFC6797, November 2012, <https://www.rfc-editor.org/info/rfc6797>.
[RFC7258]
Farrell, S. and H. Tschofenig, “Pervasive Monitoring Is an Attack”, BCP 188, RFC 7258, DOI 10.17487/RFC7258, May 2014, <https://www.rfc-editor.org/info/rfc7258>.
[RFC7301]
Friedl, S., Popov, A., Langley, A., and E. Stephan, “Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension”, RFC 7301, DOI 10.17487/RFC7301, July 2014, <https://www.rfc-editor.org/info/rfc7301>.
[RFC7595]
Thaler, D., Ed., Hansen, T., and T. Hardie, “Guidelines and Registration Procedures for URI Schemes”, BCP 35, RFC 7595, DOI 10.17487/RFC7595, June 2015, <https://www.rfc-editor.org/info/rfc7595>.
[RFC7605]
Touch, J., “Recommendations on Using Assigned Transport Port Numbers”, BCP 165, RFC 7605, DOI 10.17487/RFC7605, August 2015, <https://www.rfc-editor.org/info/rfc7605>.
[RFC7616]
Shekh-Yusef, R., Ed., Ahrens, D., and S. Bremer, “HTTP Digest Access Authentication”, RFC 7616, DOI 10.17487/RFC7616, September 2015, <https://www.rfc-editor.org/info/rfc7616>.
[RFC7617]
Reschke, J., “The 'Basic' HTTP Authentication Scheme”, RFC 7617, DOI 10.17487/RFC7617, September 2015, <https://www.rfc-editor.org/info/rfc7617>.
[RFC8297]
Oku, K., “An HTTP Status Code for Indicating Hints”, RFC 8297, DOI 10.17487/RFC8297, December 2017, <https://www.rfc-editor.org/info/rfc8297>.
[RFC8446]
Rescorla, E., “The Transport Layer Security (TLS) Protocol Version 1.3”, RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.
[RFC8470]
Thomson, M., Nottingham, M., and W. Tarreau, “Using Early Data in HTTP”, RFC 8470, DOI 10.17487/RFC8470, September 2018, <https://www.rfc-editor.org/info/rfc8470>.
[RFC8949]
Bormann, C. and P. Hoffman, “Concise Binary Object Representation (CBOR)”, STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, <https://www.rfc-editor.org/info/rfc8949>.
[SECCTXT]
West, M., “Secure Contexts”, W3C Candidate Recommendation, September 2021, <https://www.w3.org/TR/2021/CRD-secure-contexts-20210918>.
[URI-TEMPLATE]
Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., and D. Orchard, “URI Template”, RFC 6570, DOI 10.17487/RFC6570, March 2012, <https://www.rfc-editor.org/info/rfc6570>.
[XML]
Bray, T., Paoli, J., Sperberg-McQueen, M., Maler, E., and F. Yergeau, “Extensible Markup Language (XML) 1.0 (Fifth Edition)”, W3C Recommendation REC-xml-20081126, November 2008, <https://www.w3.org/TR/2008/REC-xml-20081126>.

Appendix A. RFC 3205 からの変更点

[RFC3205] は 2000 年代初頭のプロトコル設計者が直面していた懸念に基づき最良の現行慣行を捉えていました。その後の HTTP の使用法は大きく変化したため、本書は実質的に異なります。その結果、変更点は個別に列挙するには多すぎます。


著者の連絡先

Mark Nottingham
Prahran
オーストラリア
EMail: mnot@mnot.net
URI: https://www.mnot.net/