web.devで以下の記事を見つけました。
ちなみに、web.devはGoogleが運営するサービスで、サイトの分析を計測したり、他にもwebに関する有益な情報を発信しています。
この記事を要約すると、
- target=”_blank”属性はパフォーマンスとセキュリティ上の問題を起こしうる
- rel=”noopener” もしくは rel=”noreferrer”属性を付加することで対策可能
というものです。
実例も入れながら、検討してみます。
target=”_blank”の何が問題か
上のサイトでは2つ問題点が挙げられています。
- リンク先のページで大量のJavaScriptが走ると、呼び出し元がパフォーマンス上の影響を受ける
- リンク先のページがwindow.opener属性を使うことで、呼び出し元ページのURLを悪意あるページに書き替えることが可能(セキュリティ上の問題)
「2」は要するに、CSRF (Cross Site Request Forgery)が可能です。
つまり、悪意あるスクリプトが埋め込まれたページを閲覧者の意図と関係なく閲覧者に実行させることが可能、ということですね。
1.パフォーマンス上の問題
起点となるサイト(リンク元のサイト)と同一のプロセスでリンク先ページが実行されるため、リンク先で重いJavaScriptが走ると巻き添えを食う、という仕組みです。
でも、それより怖いのは「2」です。
2.セキュリティ上の問題
リンク先のページでJavaScriptの「window.opener」を使用して、呼び出し元のサイトのURLを書き換えることができてしまいます。
要するに、悪意あるコードを閲覧者に実行させることが可能、ということです。
実際に試してみましょう。
下のリンクをクリックしてみて下さい。
サイト内(mat0401.info)の別ページが新規タブで開かれますが、呼び出し元URL(このページ)が変わってしまいます。
(リンク先は無害なページなので安心して下さいね)
上記のリンクのHTMLソースは以下の通りです。
<a href="https://mat0401.info/20200611-target-blank1/" target="_blank">テスト用ページに飛びます(無害なサイトなので安心してください)</a>
ちなみに、リンク先には以下のようなJavaScriptが仕込んであります(念押しで言いますが、無害です)。
<script>
if (window.opener) {
opener.location='https://mat0401.info/20200611-target-blank2';
} else {
document.querySelector('h1').innerHTML = 'ちゃんと対策していますね!(これは無害なテスト用ページです)'
}
</script>
今回は試しませんが、この方法を使うと別ドメインのページも閲覧者に開かせることができ、悪意ある任意にコードを実行させることが可能になってしまいます。
対策方法
target=”_blank”があるaタグの属性に、rel=”noopener”もしくはrel=”noreferrer”を付けます。
以下のような感じです。
<a href="https://mat0401.info/20200611-target-blank1/" target="_blank" rel="noopener">
テスト用ページに飛びます
</a>
noreferrerなら以下のようにします。
<a href="https://mat0401.info/20200611-target-blank1/" target="_blank" rel="noreferrer">
テスト用ページに飛びます
</a>
これもサンプルページに飛ばしたかったのですが、使用しているWordPressテーマの仕様でできなかったので、コードの提示だけとさせて下さい。
rel=”noopener”は、別プロセスとして動作させ、window.openerへのアクセスを防止する機能があります。
rel=”noreferrer”は、同様の働きをしますが、refererヘッダを遷移先のページに渡しません。
但し、一部の古いブラウザは対応していない
rel=”noopener”は、IE11は対応していません。
また、EdgeはVersion 79からの対応のようです。
Windows10初期インストールのバージョンのEdgeだと対応していないようです。
rel=”noreferrer”は、Windows10の最新IE11なら対応していて、他の主要ブラウザもよほど古いバージョンでなければ使用できるようです。
参考
・Can I use (noopener)
・Can I user (noreferrer)
終わりに
サイト内部での遷移なら不要かもしれませんが、外部サイトを新規ウインドウで開く際は、上記対策は考慮すべきでしょう。
しかし、Webの脅威・脆弱性対策はコーディングレベルで対処しなければならないことも多く、しかも新しい事象が次々に出現するので、素早い情報収集が課題になりますね。
個人的な課題でもあります。
以上です。
参考サイト
・Links to cross-origin destinations are unsafe (web.dev) 2019/5/2
・About rel=noopener (GoogleエンジニアのMathias Bynensさんの解説記事)