target=”_blank”は悪用の危険性があるので要対策

HTML+CSS

web.devで以下の記事を見つけました。
ちなみに、web.devはGoogleが運営するサービスで、サイトの分析を計測したり、他にもwebに関する有益な情報を発信しています。

Links to cross-origin destinations are unsafe - Chrome Developers
Learnhowtosafelylinktoresourcesonanotherhost.

この記事を要約すると、

  • target=”_blank”属性はパフォーマンスとセキュリティ上の問題を起こしうる
  • rel=”noopener” もしくは rel=”noreferrer”属性を付加することで対策可能

というものです。

実例も入れながら、検討してみます。

target=”_blank”の何が問題か

上のサイトでは2つ問題点が挙げられています。

  1. リンク先のページで大量のJavaScriptが走ると、呼び出し元がパフォーマンス上の影響を受ける
  2. リンク先のページが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さんの解説記事)