Security

target blankの危険性。別タブで開くリンクには必ずnoopenerをつけるべき理由

「別タブで開く」設定には、実はセキュリティ上の脆弱性(Tabnabbing)が潜んでいます。rel=noopener属性でサイトとユーザーを守る方法。

VIIO 編集部
VIIO 編集部
/
🛡️

「別タブで開く」に潜む脆弱性#

外部リンクを設置する際、ユーザーの離脱を防ぐために target="_blank"(別タブで開く)を使うことはよくあります。 しかし、これには Tabnabbing(タブナビング) と呼ばれる深刻なセキュリティリスクが潜んでいることをご存知でしょうか?

Tabnabbing の仕組み

  1. ユーザーが悪意のあるサイトへのリンクを target="_blank" でクリックする。
  2. 新しいタブで悪意のあるサイトが開く。
  3. 悪意のあるサイトのJavaScript (window.opener) が、**リンク元のタブ(あなたのサイト)**を操作し、偽のログイン画面(フィッシングサイト)などにリダイレクトさせる。
  4. ユーザーが元のタブに戻ったとき、再度ログインを求められたと思い込み、ID・パスワードを入力して盗まれる。

1. 対策:rel="noopener"#

この脆弱性を防ぐ方法は非常にシンプルです。 target="_blank" を使うときは、必ず rel="noopener" 属性をセットで記述します。

Code
<!-- Bad: 脆弱性あり -->
<a href="https://evil.com" target="_blank">外部サイトへ</a>

<!-- Good: 安全 -->
<a href="https://example.com" target="_blank" rel="noopener">外部サイトへ</a>

rel="noopener" をつけると、新しいタブから window.opener オブジェクトへのアクセスが遮断(nullになる)され、元のタブを操作できなくなります。


2. 現代ブラウザのデフォルト挙動#

幸いなことに、Chrome 88 (2021年) 以降、主要なモダンブラウザでは、target="_blank" を指定すると自動的に rel="noopener" が付与される挙動(暗黙のnoopener)に変更されました。 したがって、最新ブラウザだけを対象にするなら明示的な記述は不要になりつつあります。

しかし、古いブラウザへの互換性や、セキュリティ意識の高さを明示する(Lintツールの警告を消す)意味でも、明示的に記述することをお勧めします。


3. rel="noreferrer" との違い#

似た属性に rel="noreferrer" があります。 これは noopener の効果に加え、リンク先に 「リファラー(どのページから来たかという情報)」を送らない という効果があります。

Code
<a href="https://example.com" target="_blank" rel="noreferrer">外部サイトへ</a>

アフィリエイトリンクや計測パラメータが必要なリンクで noreferrer を使うと、成果が発生しなくなる可能性があるため注意が必要です。 セキュリティ目的だけであれば noopener で十分です。


4. React / Next.js の対応#

React や Next.js の <Link> コンポーネントや <a> タグを使用する場合、ESLintの推奨ルール(react/jsx-no-target-blank)により、rel="noopener noreferrer" が付いていないと警告が出る設定になっていることが多いです。

セキュリティは「知っているか知らないか」だけの問題です。 target="_blank" を書くときは rel="noopener" も書く。これをチームの合言葉にしましょう。

この記事をシェアする

VIIO 編集部

VIIO 編集部

VIIOのセキュリティ対策チーム。Webパフォーマンスとアクセシビリティの向上に情熱を注いでいます。複雑な技術をわかりやすく伝えることをモットーに記事を執筆中。

Webサイトの品質を、今すぐチェック。

VIIOなら、パフォーマンス、SEO、セキュリティの課題をたった10秒で可視化できます。 会員登録不要、無料で何度でも。