target="_blank"に関する危険性について
これは何
別窓リンクが必要なものにrel="noopener"をつけたい
IE11対応が必要であればrel="noreferrer"もつける
ただしnoreferrerはリファラがつかなくなるのでマーケ側と相談したほうがよい
target="_blank"とは何か
HTMLでのハイパーリンク要素 a に使われる属性。
ブラウザ内での挙動では「外部リンクを開く」ものとして使われる。
指定するルールは厳格には決まってるわけではないが、基本的には同ドメインではないハイパーリンクの場合に使用される。
target="_blank"の問題点
セキュリティの観点で下記問題点が指摘されています(パフォーマンスにについては後述します)
The other page can access your window object with the window.opener property. This may allow the other page to redirect your page to a malicious URL.
セキュリティ問題
Jxckさんのブログが詳細にまとめているのでこちらより引用します
https://user-images.githubusercontent.com/1996642/91045910-89184f80-e652-11ea-940c-e272b56cc8c6.png
攻撃者は、このサービスの不特定ユーザのユーザ名およびパスワードを盗みたいとする。
この攻撃の成立のために、サービスに必要な仕様は 任意のリンクを貼ることができて、そのリンクが target=_blank にマークアップされる ことである。
攻撃者が必要な準備は以下である。
誘導用サイト(右上)
ユーザを収集用サイトに誘導するサイトである。
(この JS が動くなら、 XSS でこのスクリプトを別サービスに仕込んでも代替できる)
収集用サイト(左下)
ユーザ情報を収集する、ダミーサイトである。
対象サイトと酷似したドメイン取得する、今回の場合 cgn.example.com など
攻撃
実際の攻撃は以下の手順で行う
- 本家サービスを利用中の他のユーザに、このリンクを踏ませる
- 被害者は、別のタブで開き、本家のタブは裏に隠れる。
- 見終わって閉じると、さっきまでの本家サイトのタブがなぜかログイン画面(左下)になっている。
- このログイン画面はダミーであり、ユーザ名/パスワードを入力すると、本家(右下)へリダイレクトする。
- 最近は遷移の途中や、一定時間経過後にログインを要求するサービスもあるため、この挙動を攻撃とは思わないユーザがいても不思議では無いだろう。
最も、自分が開いていた正しいページが、勝手に別の攻撃ページに置き換わっているという想定が一般的とは考えにくい。
最後のリダイレクトは、攻撃サイトから既にログイン済みの本家サイトにリダイレクトすることで、ユーザからみれば単にログインが成功したように見える。
つまり、攻撃自体に気づけない可能性もある。
デモページ
https://user-images.githubusercontent.com/1996642/91046261-0d6ad280-e653-11ea-9a2b-57a50e55a004.gif
https://user-images.githubusercontent.com/1996642/91045979-a2b99700-e652-11ea-931c-844163c56852.png
Lighthouse flags unsafe links to cross-origin destinations:
対応策について
rel="noopener" を付与する
現時点での確実な対応策がこれになります。
The keyword indicates that any newly created top-level browsing context which results from following the hyperlink will not be an auxiliary browsing context. E.g., its window.opener attribute will be null.
HTML Standardにおいて window.opener プロパティを無効化するという説明があります。これを使うことでセキュリティ面での不備に対応することができます。
2020年5月現在において、caniuseではIE11を除くモダンブラウザで対応できるようになっています。
上述したようにIE11ではnoopenerが使えないため、これと同等の動きができるとされている noreferrer があります。
よってモダンブラウザ+IE11で対応する場合は
code:html
hogehoge.com
</a>
といった形になります。
noreferrerの問題点
ただしnoreferrerを使用する際には注意が必要です。それは名前の通りリファラがつかなくなるということです。
リファラが恩恵を受けるものの1つでAnalyticsなどの解析です。
どのサイトから遷移してきたのかを確認することができます。noreferrerを付けることでその遷移元を確認することができなくなってしまいます。
ただ今のサイト内での遷移でreferrerがつかないことでどういった不利益があるのか、というのは付ける時に考慮してみていいでしょう。
その時の天秤で不利益のほうに下がらないのであればnoreferrerを付けるのは問題ないと思います。
たとえば社内情報共有システムやイントラネットから外部サイトへのリンクでは、rel="noreferrer" を使うのもいいだろう。その場合、rel="noopener noreferrer" のように記述すればいい。
こうしておけば、そのリンクをたどってもブラウザはアクセス先のサーバーにリファラーを送信しない。そのため、アクセス解析データやログデータから「なるほど、この会社では内部ネットワーク名がこういう命名パターンなのか」「内部ネットワークにこういうホスト名でWebサーバーが動いているのか」といったことをリンク先サイトの管理者に知られなくて済む。
パフォーマンスについて
noopenerの付属的な情報ですが、パフォーマンスが良くなるという話が見られます。
The other page may run on the same process as your page. If the other page is running a lot of JavaScript, your page's performance may suffer.
This means JavaScript running on one domain runs on a different thread to a window/tab running another domain.
However, due to the synchronous cross-window access the DOM gives us via window.opener, windows launched via target="_blank" end up in the same process & thread. The same is true for iframes and windows opened via window.open.
target="_blank"で開かれたページは、元ページとJavaScriptが同じプロセス・スレッドで動作するようです。
なので、target="_blank"で開かれたページに負荷の高いJavaScriptが実行されていると、元ページのパフォーマンス低下など影響があるということです。 参照元