【HTML】target=”_blank”の脆弱性とは?対処法はnoopener noreferrer

今回は「target=”_blank”」の脆弱性についてと、その対策として使われているrel属性noopenernoreferrerについてご紹介します。

そもそもtarget=”_blank”って?

リンクをクリックしたときに別タブで開いて表示させることができます。
例→  https://web-plus.jpが別タブで開かれます。

target=”_blank”の脆弱性って?

まとめると、「target=”_blank”」によって開かれたページは対策をしていないと、
javascriptを使って親ページ(元ページ)の操作ができてしまう。ということです。

例を挙げます。
まず、[A]というページと[B]というページがあります。
[A]のページでリンクを押し、[B]のページを新しいタブで開く仕組みにしたいです。
そこで、[A]のページで「target=”_blank”」を使い、[B]のページを開きました。
blank
[B]のページを開くことができましたが、
なぜか[A]のページが[C]という別物のページに変わってしまいました…
blank
blank
というように、親ページ(元ページ)の操作ができてしまいます。
この動きを応用して、本物そっくりのページを作り、「再ログインしてください」といった入力欄をつくり、
ユーザやパスワードの情報が取得されてしまう…というような問題があり、この攻撃をTabnabbing (タブナビング)といいます。

ちなみに今回のパターンだと、[B]のページに、

  window.opener.location = '移動させたいページ(今回なら[C])のURL';

のような簡単な記述でできてしまいます。

どうして親ページ(元ページ)の操作ができるの?

これは上の例で紹介した、[B]のページに記載されたコードのwindow.openerが原因です。

window.opener(ウィンドウ.オープナー)とは

window.openerは親となるウィンドウ、つまりは親ページ(元ページ)を参照し、操作できるJavaScriptのオブジェクトです。「target=”_blank”」を使って開かれたページは親と子の様な関係となります。
そのため開かれた子ページは、親ページ(元ページ)のwindow.openerを参照することができます。そこで
「target=”_blank”」によって子ページにwindow.openerを使ったコードが書かれてしまっていると、
親ページ(元ページ)を参照し、操作が可能になります。

この、「JavaScript」はプログラミングをするための人工言語の一つで、Webページに動きをつける時などに使われます。ここでいう「オブジェクト」というのは広い意味ではデータと処理の集合体です。概念の一つですので明確に何を指すかは曖昧です。

今回のwindow.openerで例えると、「親ページ(元ページ)」というデータがあり、そのデータを子ページが参照して「親ページのURLを書き換える」という処理があります。

blank
blank
blank

対策法は?

「target=”_blank”」によってwindow.openerオブジェクトをリンク先のページに渡してしまうことが
原因ですので、渡さないような設定にしましょう。
方法は、noopenernoreferrerを使う。または両方使うことです。

noopener(ノーオープナー)って?

「no」と「opener」という名前通り、「target=”_blank”」によって開かれたページの、window.openerを、
参照できなくします。
それ以外にメリットもあり、新しく開かれるページ分の負荷がなくなるということがあります。
「target=”_blank”」によって新規ページを開いた際に、新規ページのプラグラムなどによる負荷が重いと、
親ページ(元ページ)にも負荷がかかる場合があるのですが、その影響を受けなくなるためです。

noreferrer(ノーリファラー)って?

こちらは「referrer(リファラ)」を渡さない設定です。リファラとは、参照元のページのことを意味します。
つまりは現在のページの一つ前に見ていたページのことです。
親ページ(元ページ)のリンクなどの情報が渡されないため、noopenerと同じ効果もあります。
noopenerとの違いは、window.openerだけでなくページのリンクも参照できなくすることです。

このため、注意点が2つあります。
1つはGoogleアナリティクスなどで、サイトの分析などをする場合です。
内部リンク(自分のサイト内でのリンク)にnoreferrerを付けてしまうと、リファラが取れないため
ページがどのように移動され、閲覧されたかが分からなくなってしまう可能性があるので
内部リンクには使用しないことを推奨します。

2つ目はアフィリエイトリンクを設置する場合です。
アフィリエイトとは、企業の商品・サービスのリンクを貼り、サイト訪問者がそのリンクを経由して、
企業の商品が購入された際などに、報酬が支払われる仕組みのことです。
noreferrerだと参照元のページが分からず、どこのサイトに報酬を支払えばいいのか分からないため、注意が必要です。

noopener、noreferrerの両方を使う

こちらはブラウザの対応のためです。例えば、サポートは終了されていますが、Internet Explorerでは
noopenerが使えません。そのためnoreferrerで代用するために両方使われていました。

ブラウザの対応も幅広く、noopenerと同じ役割があることから、両方使うくらいなら
noreferrerだけで良いと思いますが、noreferrerによるリファラが取れないのが困る。
といった状況であれば逆にnoopenerだけにするなど、目的によって使い分ける必要があります。

この脆弱性をすでに対応しているブラウザ、CMSについて

  • Chrome
  • Safari
  • Firefox

の、ブラウザではセキュリティ対策として自動的にnoopenerが付与されます。
また、wordpressでも自動でnoopenerが付与されます。

まとめ

  • target=”_blank”は、対策をしないとjavascriptでページの操作ができてしまう。
  • target=”_blank”の脆弱性の対策としてnoopener noreferrerが使われている。
  • noreferrerは、目的次第では外した方が良い。
  • ブラウザ、CMSによっては自動的にnoopenerが付与される。