CSSの:visitedの仕様が変わる! 訪問済みリンクの履歴検出攻撃を無効化する機能がChrome 136に実装されます
Post on:2025年4月16日
sponsors
今月リリース予定のChrome 136で、訪問済みリンクの履歴検出攻撃を無効化する機能が実装される予定です。
簡単に説明すると、:visited
によるリンク履歴が分割される機能が実装され、サイトA上でクリックしたサイトBへのリンクは、サイトA上では訪問済みになりますが、サイトC上のサイトBへのリンクは訪問済みにはなりません。履歴にはサイトBへのリンクはサイトA上でという情報も加わるようになります。

Making :visited more private
by Kyra Seevers
下記は各ポイントを意訳したものです。
※元サイト様のライセンスに基づいて翻訳しています。基づいてというのは、貢献部分に関して同ライセンスも含みます。
はじめに
リンクをクリックするとどうなるでしょうか?
リンクカラーが通常の設定であれば、ブルーからパープルに色が変わります。
インターネットの黎明期からWebサイトではCSSの:visited
セレクタを用いて、ユーザーがクリックしたこのあるリンク(訪問済みリンク)にカスタムスタイルを適用してきました。:visited
セレクタを使用することで、Webサイトはユーザーエクスペリエンスを向上させ、ユーザーのWebナビゲーションを支援してきました。しかし、訪問済みリンクのカスタマイズ性が高まるにつれ、セキュリティ研究社によって発見された攻撃の数も増加しています。
これらの攻撃は、ユーザーがどのリンクを訪問したかを明らかにし、Web閲覧アクティビティの詳細が漏えいする可能性があります。このセキュリティ問題は20年以上に渡ってWebを悩ませており、ブラウザはこれらの履歴検出攻撃を軽減するためにさまざまな対策を講じてきました。これらの対策によって攻撃は原則されたものの、完全に排除されたわけではありません。
Chrome 136は、これらの攻撃を無効化する最初のブラウザです。この機能は、:visited
のリンク履歴を分割することで実現されます。
:visitedのリンク履歴を分割とは
ブラウザはあなたが過去に訪れたリンク(訪問済みリンク)を表示するために、過去に訪れたページを記録しておく必要があります。これは:visited
履歴と呼ばれます。CSSの:visited
セレクタを使用すると、訪問済みリンクと未訪問のリンクを異なるスタイルで表示することができます。
1 2 3 4 |
:visited { color: purple; background-color: yellow; } |
これまでは、: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