
CSS おれおれ Advent Calendar 2012 – 15日目
一昔前に訪問済みのリンクの色が変わる代わりにチェックマークが付く、というようなのを見た事があるんですが、現在は出来ません。
訪問済みのリンクの背景画像を変える、というCSSは利用できません。無視されます。
おさらい
本題へ入る前にCSSのおさらいを。
:visited
訪問済みリンクを示すセレクターです。なお未訪問のリンクは:linkで得られます。
いずれもリンクを前提としているので、要素aの指定は省略して問題ないでしょう。
background-image
背景画像を指定するプロパティです。読み込みに時間がかかる場合もあるので、background-colorも一緒に指定しておきましょう。(してないとこ多いんですよね……。)
background-positionを使ったCSSスプライトという技術も有名ですね。
プライバシー情報漏洩の仕組み
さて閑話休題。この二つを組み合わせて悪用すると、「(他サイトへの)訪問履歴」を得る事が出来てしまいます。
background-imageが:visitedと一緒に使える場合を考えます。
この時に問題になるのが、「画像を読み込む」つまり「画像をウェブサーバーへ要求する」という当たり前の行為です。
要求を受け取ったウェブサーバーは、要求している画像のURLを知っています。当然ですよね。すると、こんな事ができます。
- ユーザー(A)がウェブページを開く。
- このページにはエロサイト(X)へのリンク(L)が含まれている。
- CSSで、(L)の
:visited用のスタイルとして、画像(G)を読み込む。 - サーバーは、ユーザー(A)がエロサイト(X)へ訪問した事があると知る。
- 事前に画像(G)はエロサイト(X)へのリンク専用としておく。

「エロサイト(X)」は「楽天の商品ページ」や「気になるあの子のmixi」、あるいは「URLを知ってる人だけに公開されている秘密のページ」なんかに置き換えても同じです。
こりゃ困るぞという事で、使えなくなっています。
:visitedと一緒に使えるもの、使えないもの
プロパティ
ブラックリスト(使えないものリスト)ではなくホワイトリスト(使えるものリスト)で管理されてます。
colorbackground-colorborder-*-coloroutline-color
色を変えるものだけですね。また色も、透過の指定ができません。rgba()とhsla()では設定した透明度は無視され(色は変わる)、transparent) は利用できません。
セレクター
訪問済みリンク:visitedを起点とする検索も行えないようです。
つまり子孫:visited spanや兄弟:visited + span、あるいは疑似要素:visited::beforeなどが使えないみたいです。
なんで制限がきついのかというと
画像関係ないなら良いじゃん、という風に思われるかもしれませんが、そうでもありません。
ウェブ系の脆弱性、情報漏洩の流行はやっぱりJavaScriptです。(胸を張って言う事じゃないですねえ。) 例えばフォントサイズを変更できると、JavaScriptから領域の大きさを得て判断する事ができてしまいます。
なおJavaScriptから「現在使用されているスタイル」を得る事ができる (.getComputedStyle()) のですが、そちらも「常に:linkの情報を返す」というようになっています。色だけ許容されているのは、これのおかげです。色が変わっても他に影響がなく、検知できないですから。
対応状況
Firefox
最初にこの問題に対応しました。
今回の記事は、基本的にこの記事に基づいています。
Webkit (Chrome, Safari)
Firefoxに倣い同様の修正を行いました。
IE
「モダンブラウザー」に仲間入りした9でこの問題に対応したようです。
IE 8は、試したところ利用可能でした。(つまり未対応です。)
Opera
未対応みたいです。最新版で試してみましたが、background-image等々が利用可能でした。
というわけで
:visitedだからといって派手にスタイルを切り替える場面ってのはあまりないと思うのですが、あんまりアレコレできないので気を付けましょう。
ちゃんちゃん。