CSSの:visitedの仕様が変わる! 訪問済みリンクの履歴検出攻撃を無効化する機能がChrome 136に実装されます

今月リリース予定のChrome 136で、訪問済みリンクの履歴検出攻撃を無効化する機能が実装される予定です。

簡単に説明すると、:visitedによるリンク履歴が分割される機能が実装され、サイトA上でクリックしたサイトBへのリンクは、サイトA上では訪問済みになりますが、サイトC上のサイトBへのリンクは訪問済みにはなりません。履歴にはサイトBへのリンクはサイトA上でという情報も加わるようになります。

訪問済みリンクの履歴検出攻撃を無効化する機能がChrome 136に実装されます

Making :visited more private
by Kyra Seevers

下記は各ポイントを意訳したものです。
※元サイト様のライセンスに基づいて翻訳しています。基づいてというのは、貢献部分に関して同ライセンスも含みます。

はじめに

リンクをクリックするとどうなるでしょうか?
リンクカラーが通常の設定であれば、ブルーからパープルに色が変わります。

インターネットの黎明期からWebサイトではCSSの:visitedセレクタを用いて、ユーザーがクリックしたこのあるリンク(訪問済みリンク)にカスタムスタイルを適用してきました。:visitedセレクタを使用することで、Webサイトはユーザーエクスペリエンスを向上させ、ユーザーのWebナビゲーションを支援してきました。しかし、訪問済みリンクのカスタマイズ性が高まるにつれ、セキュリティ研究社によって発見された攻撃の数も増加しています。

これらの攻撃は、ユーザーがどのリンクを訪問したかを明らかにし、Web閲覧アクティビティの詳細が漏えいする可能性があります。このセキュリティ問題は20年以上に渡ってWebを悩ませており、ブラウザはこれらの履歴検出攻撃を軽減するためにさまざまな対策を講じてきました。これらの対策によって攻撃は原則されたものの、完全に排除されたわけではありません。

Chrome 136は、これらの攻撃を無効化する最初のブラウザです。この機能は、:visitedのリンク履歴を分割することで実現されます。

:visitedのリンク履歴を分割とは

ブラウザはあなたが過去に訪れたリンク(訪問済みリンク)を表示するために、過去に訪れたページを記録しておく必要があります。これは:visited履歴と呼ばれます。CSSの:visitedセレクタを使用すると、訪問済みリンクと未訪問のリンクを異なるスタイルで表示することができます。

これまでは、:visited履歴は分割されていませんでした。つまり、:visitedセレクタを使用して:visited履歴を表示する場所に制限がなかったことを意味します。リンクをクリックすると、そのリンクを表示しているすべてのサイトで:visitedとして表示されます。これは、攻撃者がユーザーの閲覧履歴に関する情報を漏えいできるため、設計上の核心的な欠点でした。

次の例を考えてみてください。
サイトAを閲覧中にリンクをクリックしてサイトBに移動したとします。このシナリオでは、サイトBがvisited履歴に追加されます。その後、サイトBへのリンクがある悪意のあるサイトにアクセスしたとします。:visited履歴は分割されていない場合、悪意のあるサイトではサイトBへのリンクを:visitedとして表示します。そして、悪意のあるサイトはセキュリティ上の脆弱性を利用して、リンクが:visitedとしてスタイル設定されているかどうかを把握し、ユーザーが過去にサイトBにアクセスしたことを把握し、閲覧履歴に関する情報を漏えいする可能性があります。

この流れを図にして見てましょう。
まずは、:visited履歴は分割されていない場合です。

サイトのキャプチャ

サイトBのリンクをクリック。

サイトのキャプチャ

サイトBをクリックすると、そのリンクを表示するすべてのサイト(悪意のあるサイトを含む)で:visitedで表示されます。

すべてのサイトで:visitedで表示されます。

:visited履歴を分割とは、以前にこのサイトからそのリンクをクリックしたことがある場合にのみ訪問済みとして表示することで、閲覧履歴を保護します。つまり、このサイトを以前に利用したことがない場合は、:visitedとして表示されません。

上記の例で今度は、:visited履歴を分割した場合を見てましょう。
サイトAを閲覧中にリンクをクリックしてサイトBに移動すると、「サイトA+サイトB」の組み合わせが:visited履歴に保存されます。こうすることで、悪意のあるサイトにアクセスしても、サイトBへのリンクは:visitedで表示されることはありません。これは「サイトA+サイトB」の両方の要素と一致しないためです。悪意のあるサイトには閲覧履歴が表示されないため、悪用されることはありません。したがって、あなたのブラウザ履歴は安全になります!

この流れを図にして見てましょう。
今度は、:visited履歴が分割されている場合です。

サイトのキャプチャ

サイトBのリンクをクリック。

サイトのキャプチャ

サイトA上のサイトBへのリンクは訪問済みになりますが、それ以外のサイト(悪意のあるサイトを含む)では訪問済みにはなりません。

サイトのキャプチャ

リンクをクリックしたサイトA上のみ:visitedで表示されます。

:visited履歴の分割を簡単に説明すると、リンクがクリックされた場所に関する情報も追加して保存するということです。ChromeではこれはリンクURL、トップレベルサイト、フレーム元がこれにあたります。分割を有効にすると、:visited履歴はどのサイトからも照会できるグローバルなリストではなくなります。その代わりに、:visited履歴は分割され、最初にリンクをクリックした場所のコンテキストごとに分けられます。

同じサイト内の他のページへのリンクはどうなるか

インターネットを閲覧していると、多くのリンクをクリックして、同じサイトの異なるサブページに戻ってしまうことがあります。たとえば、さまざまな種類の金属を調べるときにSite.Wikiの「クロム」と「真鍮」のページをアクセスしたとします。

:visited履歴の分割を厳密に実装すると、ユーザーがゴールドのSite.Wikiページにアクセスしても、クロムや真鍮のページへのリンクを:visitedにすることはできません。これはユーザーがこれらのページをクリックしたのが金のSite.Wikiページと一致しないトップレベルサイトだからです。

サイトのキャプチャ

このような状況において分割のプライバシーとセキュリティの保護を維持しつつユーザーエクスペリエンスを向上させるために、セリフリンクの例外を導入しました。

セリフリンクの例外とは簡単に言うと、サイトはそのコンテキストで以前にリンクがクリックされたことがない場合でも自身のサブページを:visitedとして表示できます。サイトにはユーザーがサブページを訪問したかどうかを追跡する他の方法があるため、セルフリンクの導入によってこれらのサイトに新しい情報が与えられることはありません。

分割は依然としてクロスサイトトラッキングから保護し、同一オリジンポリシーを実施します。ただし、これはサイト自身のサブページへのリンクのみ適用されることに注意してください。サードパーティのサイトやサードパーティのiframeへのリンクは、この例外の対象外です。

セルフリンク除外後は、下記のようになります。

サイトのキャプチャ

この機能の実装状況

:visitedのセキュリティとプライバシーに関する改善は、Chrome 136から提供されます。Chromeはこれらの保護機能を実装した最初のブラウザとなります。

sponsors

top of page

©2025 coliss