target=”_blank”の脆弱性について ~noopener、noreferrerとは?~

HTML

Webサイトでリンクを別タブで開く指定である、aタグの「target=”_blank”」。

<a href="path/to/file/index.html" target="_blank" >別タブへリンク</a>

このように記述すれば、リンクテキストがクリックされた際に別タブでリンク先を開かせることが可能です。
HTMLを勉強し始めると、わりと最初のほうに出会う記述法だと思います。

しかし、そんな初学者にもなじみの深いtarget=”_blank”は、実は脆弱性が指摘されています。
「target=”_blank” 脆弱性」などでググればたくさんの情報がヒットしますが、ここでは学習としてまとめておきたいと思います。

target=”_blank”が抱える脆弱性とは一体何でしょうか。

スポンサーリンク

target=”_blank”の何が問題?

target=”_blank”を利用してリンクをすると、自サイトのタブとは別の新規タブが開いてリンク先が表示されます。
その際リンク先のサイトに悪意あるJavaScriptのコードが記述されていると、リンク元のサイト(つまり自サイト)のURLなどを不正に書き換えられてしまう可能性があります。

悪意ある第三者にURLを書き換えられた結果として何が起こるかというと、

  1. 別タブで開いたリンク先を閲覧し終わったユーザーが自サイトに戻ってくる
  2. その時にはすでに自サイトとは別の、偽サイトなどに誘導されている
  3. ユーザーは不正なページ上でID・パスワードの入力をさせられたり、個人情報を盗まれるなどの被害に遭う

といった犯罪に至る可能性があります。
こんなことが起これば、ユーザーはあたかもリンク元ページ(自サイト)で被害に遭ったように思ってしまいます。実際にはリンク先のページでURLを書き換えるプログラムが実行されているのですが、タブが違うのに別サイトに誘導されている、なんてかなりの確率で気が付かないでしょう。

そのような状況には陥りたくないですよね。ではどうすればよいでしょうか。
解決策は、自サイトからリンクさせるタイミングで、リンク先の悪意ある記述を動かなくさせることです。

脆弱性の回避方法

「target=”_blank”を使用しない!」というのは極論ですし、無理があると思います。
やはりアクセスの担保やユーザーの利便性などにおいて「target=”_blank”を使ったほうが良い」ということが多いでしょう。

そこで、この脆弱性を回避するための記述を加えます。
それは

rel=”noopener noreferrer”

という記述を、aタグにtarget=”_blank”と一緒に書いてあげます。
つまり

<a href="path/to/file/index.html" target="_blank" rel="noopener noreferrer">別タブへリンク</a>

と記述してあげるわけですね。
※場合によっては「noreferrer」は書かないほうがよいこともあるようです。これについては後述します。

コラム

リンク先で悪さをする可能性のあるJavaScriptのコードは「window.opener」といったものです。
これが悪意を持ってリンク先に書かれていると、target=”_blank”からジャンプした際にリンク元サイトのオブジェクトが操作されたり、URLを改変されたりする可能性があります。
その知識を前提に、次のセクションでは属性値の意味をご説明します。
(window.openerの操作性を知ったとはいえ、悪用は厳禁ですよ!)

属性値の意味を解説

noopener、noreferrerとは?

target=”_blank”の脆弱性回避として「rel=”noopener noreferrer”」を付与するのですが、「noopener」「noreferrer」って何?というところがわかっていないと、どういう意図でこの記述を書いているのかを理解できず覚えにくいと思いました。(初学者のうちなどは、単に”おまじない”と覚えてもいいかもしれませんが。)

そこで、属性値である「noopener」「noreferrer」の意味についても調べましたのでまとめておきます。

noopener

パッと見「ん?ぬーぷ…??何??」と思いますが、これは「no opener」(ノー オープナー)です。つまり簡単に言えば、リンク先に書かれたwindow.openerの動作を止めるものです。次に解説するnoreferrerと違って、window.openerそのものに対して有効性があります。noopenerに対応しているブラウザであれば、「rel=”noopener”」とだけ記述しても回避になるようです。

リンク先が絶対的に信頼できるのであれば必ずしもつける必要はないのかもしれませんが、個人的にはいつ何が起こるかわからないので基本的にはつけておいたほうが良いのだろうと思います。調べた限りでは、noopenerが記述されていることによる不都合等は確認できませんでした。

動作対象が限定的なので便利ですが、IEではサポートされていないため動作しません。

参考URL:
その他ブラウザでのサポート状況は以下を参照してください。
Can I Use – rel=”noopener”

noreferrer

こちらは「no referrer」(ノー リファラ)です。
リファラとは、たとえば「どのリンク元ページから来たのか」などの、リンク元からの情報を差します。

「rel=”noreferrer”」とすることで、リファラが送信されなくなります。そのためリンク先のページはリンク元の情報を参照できず、結果としてwindow.openerが動作できないということになるわけですね。

こちらはIEもサポートされているので、IEでも動作します(windows 10 の IE 11 のみに対応)。

参考URL:
その他ブラウザでのサポート状況は以下を参照してください。
Can I Use – rel=”noreferrer”

noreferrerの注意点

アクセス解析や広告掲載をしているサイトなどでは、アクセス数のカウントや収益計上などのためにリファラが必要になる場合があります。 rel=”noreferrer”はリファラを送信しないので、それらが正常に機能しなくなることがあるようです。そのためnoreferrerに関しては、望む挙動によっては記載しないほうが良い、ということもあります。
noopenerよりも使用できるブラウザは少し多いのですが、影響を及ぼす範囲も広い、ともいえるのでその点を理解して使用する必要があるしょう。

まとめ

target="_blank"にはrel="noopener"を必ず付与しよう

今回はtarget=”_blank”の持つ脆弱性とその回避方法を学びました。

個人的には、まだそこまで本格的に自分でJSを書いていないこともあり「なぜそんな危険なスクリプトが存在しているんだろう」と思ってしまいますが、
悪用せずにちゃんとした方法で使えば、きっと便利なスクリプトやメソッドなのだろうな、と思います。

最初に書いたようにtarget=”_blank”は初学者でも扱う記述ですし、私のように経験の浅いコーダーも脆弱性などについてはよくわからないまま扱っているということがあるかもしれません。
rel属性ひとつでブロックできる脆弱性ですから、この機会に覚えて忘れないように記述していきたいものです。

ここまで読んでいただき、ありがとうございました。

追記 ※2022/11/13

MDNのHTMLのリファレンスを参照すると、2022/11時点ではすでに
target="_blank"を設定した段階で暗黙的に「rel=”noopener”」が設定されたものとして動作するようになっているようです。

ただし、ブラウザによっては対応していないものもあるので、確認しておきましょう。

MDNリファレンス target=”_blank”

参考URL

【HTML】「target=_blank」は使用NG?aタグの脆弱性が話題に
https://webegins.com/target-blank/
アクセス日:2020/8/18

「target=”_blank”」の危険性
https://www.1st-net.jp/blog/2019/03/03/%E3%80%8Ctarget_blank%E3%80%8D%E3%81%AE%E5%8D%B1%E9%99%BA%E6%80%A7/
アクセス日:2020/8/18

セキュリティ対策のため、target=”_blank”のa タグに “noopener noreferrer”のrel属性を自動で付与するjavascript文
https://qiita.com/TeruhisaFukumoto/items/eeabfc838eea1ed65023
アクセス日:2020/8/18

実はヤバい?危険な「別タブで開く(target=”_blank”)」
https://wwg.co.jp/blog/3807
アクセス日:2020/8/18

知らなかった aタグに target=”_blank” の脆弱性。使う時は rel=”noopener” をつけとこう。
https://canvas-i.com/html-noopener/
アクセス日:2020/8/18

この記事を書いた人
葵

28歳未経験から、職業訓練校を経てWebコーダーに。
日々の勉強の記録や、普段使用している技術やツールなどを書き残すためにブログをはじめました。
どうぞよろしくお願いいたします。

著者をフォローする
HTML
スポンサーリンク
著者をフォローする
Web制作向上ダイアリー

コメント

タイトルとURLをコピーしました