いろいろなところで語られているのでまとめる
問題となるポイント
昔から別ウィンドウや別タブを開くときに書くHTMLは以下の通り
<a href="https://example.com" target="_blank">ここを押すと新しいウィンドウが開きます</a>
この target="_blank"
だが、開かれたページ(上記で言うところの https://example.com
から window.opener
を使うとaタグを埋め込んだ側のページの情報が取得できるため、遷移元のサイトに関して処理を加えることができる。
解決策
openerを無効化するリンク種別情報をつける
a
タグはその相手との関係性を rel
を用いてリンク種別情報がつけられるタグです。そのためこの rel
に noopener
をつけることで window.opener
の設定を無効化することができます。
<a href="https://example.com" target="_blank" rel="noopener" >ここを押すと新しいウィンドウが開きます</a>
詳しい説明をMDNより引用すると以下の通り
これは信頼できないリンクを開く際、 Window.opener プロパティでリンク元の文書を変更できないようにするために特に役に立つリンク種別です。ただし、 Referer HTTP ヘッダーは(noreferrer を使用しない限り)提供します。 - リンク種別 - HTML: HyperText Markup Language | MDN
これは各ブラウザ側が対応するものとなっていますが、最新のブラウザは概ね対応をしています。
ただし古いブラウザでは対応できていないものではあるため、そこまで視野に入ったWebアプリケーションの場合はどうすればいいかというときに出てくるのが noreferrer
です
noreferrerをつけてリファラー情報をすべて渡さない
noreferrerの意味は以下の通り
別のページへ移動する際にリンク元ページのアドレスなどの値を、ブラウザーが Referer: HTTP ヘッダーでリファラーとして送信しないようにします。 - リンク種別 - HTML: HyperText Markup Language | MDN
こちらは全般的に元ページの情報を渡さないため、前述の noopener
相当の効力を持つことができます。また noreferrer
のほうがブラウザのバージョンのカバー率が高いので特にリファラなどを渡さないことに問題ない場合はこちらを使ったほうが良い。
どちらを書くと良さそうか
情報を統合すると
という形になると思われる。
余談:主要ブラウザの動き
ChromeもFirefoxもrel属性が未指定の場合は noopener
相当の挙動をするのがデフォルトになっているのが昨今の動向なので、この点を意識しなくても問題なくなりつつあるが、認識をしておかないと痛い目を見ることがありそうなので明示的に書いておいたほうがよさそうである。
「Firefox 79」からtarget=“_blank”なリンクの挙動が変更、より安全な仕様に - 窓の杜