· 4分で読了

より安全なリクエストヘッダー - Fetch Metadata Request Headers

この記事は中国語から自動翻訳されたものです。翻訳によりニュアンスが失われている場合があります。

ある日ページを開発していたとき、リクエストヘッダーの項目が正しいか確認するために開発者ツールを開いたところ、リクエストに見慣れない不審なヘッダーがいくつか増えていることに気づいた。

何かおかしい点に気づいただろうか?よく見てみると、なんと Sec-Fetch-* で始まるヘッダーが3つもある。 これが僕の注意を引いた。僕自身はこれらのヘッダーを設定していないし、他のライブラリを適用したわけでもないのに、なぜ勝手にヘッダーが追加されているのだろうか。おそらくブラウザの仕業だろうと推測した。

Googleで調べてみたところ、これは Fetch Metadata Request Headers という新しいドラフト仕様であることがわかった。今のところこれらのヘッダーを追加するのはChromeだけで、FirefoxやSafariでは付与されない。

再び同一生成元ポリシー(CORS)について

誰もが知っている通り、ブラウザは悪意ある人物が不正な手段でデータを盗み取るのを防ぐため、オリジンごとのアクセス条件を制限している。例えばクロスオリジンリクエスト時には Access-Control-Allow-Origin の付与やPreflightリクエストが必要だったりする。詳細については、以前僕が書いた「如何和 CORS 與 Cookie 打交道」を参照してほしい。

それでもなお欠陥はある。例えば <img/> は依然としてクロスオリジンリクエストを送信できるため、悪意ある人物はCORSの制限を回避できてしまう。もちろん、サーバー側で基本的な防御策を講じていれば、安全でないリクエストの大部分は防ぐことができる。

もしリクエスト送信時に、そのリクエストがどこから来たのかを説明する追加のヘッダー情報(メタデータ)を付加できれば、サーバーもヘッダーに基づいて適切なレスポンスを返すことができる。こうして生まれたのがこのドラフト仕様だ。

ヘッダー仕様:

現在、ドラフトには主に4つのヘッダーが含まれている:

1. Sec-Fetch-Dest

このリクエストの送信先(宛先)がどこかを表す。

取りうる値には audio、document、font、image、object、serviceworker など がある。これにはいくつかのメリットがあり、これらのヘッダーによる判定があれば、サーバーはそのリクエスト元が正当かどうかを即座に把握できる。例えば、リクエスト元が <img> なのにサーバーに対して画像を要求していない場合、十中八九攻撃者であるため、直接エラーを返すことができる。

2. Sec-Fetch-Mode

リクエストのモードを表す。主に cors、navigate、nested-navigate、no-cors などがあり、そのリクエストのモードが何であるかを判断する。fetch における mode に似ている。

例えば Set-Fetch-User を通じて、ユーザーが操作(クリックやキーボードなど)によってリクエストを発行したかどうかも知ることができる。

3. Sec-Fetch-Site

リクエストの送信元が同一オリジンかクロスオリジンかを表す。

4. Sec-Fetch-User

このヘッダーの値は真偽値(boolean)であり、リクエストが navigation request(リクエストの送信先が document)かつユーザーのインタラクション(ボタンの押下やキーボード操作など)があった場合にのみ true になる。サーバーはこのヘッダーに基づいて、ユーザーがリクエストをトリガーした方法が正当かどうかを判断できる。

例えばフォームの送信をクリックした際、document からリクエストが送信され、かつユーザーのインタラクション(ボタンクリックによる送信)があるため、Set-Fetch-User は ?T となる。

ヘッダーを削除する方法はあるのか?

正式な仕様の一部となった場合、これを取り除くことはおそらくできないだろう。また、これらは forbidden headers の一種であるため、手動設定でヘッダーの値を書き換えることもできない。

結論

従来このような対策を行うにはカスタムヘッダーを使って防御するのが一般的だったが、偽造される可能性が残る上に、カスタムヘッダーを追加するとPreflightのチェックが必要になり、手間が一つ増えてしまっていた。仕様レベルで導入されるメリットは、これらのヘッダーを容易に改ざんできず、統一された標準が提供される点にある。これらのヘッダーがあれば、バックエンドがリクエストを受信した際により多くの判断を行えるようになり、セキュリティを向上させることができる。

関連記事

他のトピックを探索