CSP3 で導入される navigate-to を整理してみる

WebAppSec のメーリングリスト で降ってきて気がついたんですが、2018/02/16 に CSP Level 3 の Editor’s Draft が更新されています。そこで navigate-to ディレクティブ への記述が明確になったので、少し整理してみたいと思います。

以下、読み違えや解釈違いがあれば、マサカリお待ちしています…!

上記の Editor’s Draft では、次のように navigate-to ディレクティブが説明されています。

The navigate-to directive restricts the URLs to which a document can initiate navigations by any means (a, form, window.location, window.open, etc.). This is an enforcement on what navigations this document initiates not on what this document is allowed to navigate to. If the form-action directive is present, the navigate-to directive will not act on navigations that are form submissions.

navigate-to ディレクティブは form, window.location, … で遷移する先を制限するディレクティブ、とのことです。ナビゲーションを遷移と言い換えたのは少しニュアンス違いかもしれないですが、根本的なイメージはこうだと思います。便利。

フォームに関しては既に form-action というディレクティブがあって、action 先を制限できるのですが、form の submission に関しては form-action のほうが強いことも明示されています。

(NOTE: navigate-to で制限されるのは、navigation の “initiate” であって、navigation される先ではないです、と強調されているように思います。これはリダイレクトの絡みもあるからこその表現なのではないかな?と思っていますが、強い人のマサカリが欲しいところです。)

navigate-to ディレクティブが指定されていると、次のような手順で Pre-Navigation Check なるものが行われます。あるナビゲーションが許可されるなら Allowed, 拒否されるなら Blocked を返すチェックです。

  1. ナビゲーションが form の submit によるもので、form-action ディレクティブが指定されているならば、Allowed を返す (つまり判断は form-action 側に委ねられる)
  2. ルール中に ‘unsafe-allow-redirects’ キーワードが指定されていれば Allowed を返す。e.g. navigate-to: 'unsafe-allow-redirects';
  3. ルール(source list 中にあるか?)にマッチしていなければ、Blocked を返す
  4. Allowed を返す

'unsafe-allow-redirects' キーワードが指定されている場合は、最後飛んだ先がリスト内にあれば良い、という動きにしたかったからこそのこういう流れなのではないかなと。確かに(負荷など種々の事情で)リダイレクトが間に挟まる場合も考えられるので、妥当な印象を受けます。

ナビゲーションの行き先に関しても、Navigation Response Check なるものが次の手順で行われます。

  1. check type が response なら Allowed を返す。
  2. ナビゲーションが form の submit によるもので、form-action ディレクティブが指定されているならば、Allowed を返す(判断は form-action 側に委ねられる)
  3. ルール中に ‘unsafe-allow-redirects’ キーワードが指定されていなければ、Allowed を返す。
  4. ナビゲーション結果のレスポンスがリダイレクトならば、Allowed を返す。
  5. ルール(source list 中にあるか?)にマッチしていなければ、Blocked を返す
  6. Allowed を返す。

3 番が Pre-Navigation Check と逆のことを言っているので注意です。これのお陰でリダイレクトが続いても、終点のホストがこのディレクティブで指定されたルールで必ず検査されることになっています。

導入のきっかけ

Github のこの issue に経緯があります。面白い。2016 年に始まったこの issue ですが、正式に仕様入りしたのは Github のこのコミット みたいです。

実用例: Secure Headers

まだ(2018/03/22)各ブラウザでの実装はされていないみたいですが、もう導入しようという動きはあって、たとえば Secure Headers に navigate-to を導入しようというプルリク が投げられていました。動きが早い。

あとがき

W3C の仕様を読むのに慣れてなくて微妙に厳しいんですが、”check type” とかいうもの、なんとなく自分の理解が曖昧な気がしています。”source” と “response” という語で何がいいたいのかをふわっとしか理解できていない気がする。定義はどこや〜〜。

Written on March 22, 2018