1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

別タブで開くリンクのセキュリティ対策

1
Posted at

はじめに

外部リンクを target="_blank" で別タブに開く実装はよく使われるが、セキュリティ上のリスクがあります。
この記事では、リスクの仕組みと正しい対策方法をまとめます。

タブナビング攻撃とは

攻撃の仕組み

target="_blank" で開かれた新しいタブは、デフォルトで元のページへの参照(window.opener)を持つ。
攻撃者はこの参照を利用して、元のページのURLを書き換えることができる。

// 悪意のあるサイト側のコード例
if (window.opener) {
  window.opener.location = "https://fake-login.example.com";
}

攻撃の流れ

  1. ユーザーが正規サイトで外部リンクをクリック
  2. 新しいタブで外部サイトが開く
  3. 外部サイトが window.opener.location を使い、元のタブを偽のログインページにリダイレクト
  4. ユーザーが元のタブに戻ると、偽のログインページが表示されている
  5. 「セッションが切れた」と思い込み、IDとパスワードを入力してしまう

ユーザーから見ると元のタブのURLが変わっただけなので、攻撃に気づきにくいのが特徴。

対策に使う属性

rel="noopener"

window.opener への参照を null にし、新しいタブから元のページを操作できなくする。

<a href="https://example.com" target="_blank" rel="noopener">リンク</a>

rel="noreferrer"

リファラー情報(どのページからアクセスしてきたか)を送信しない。noopener の効果も含む。

<a href="https://example.com" target="_blank" rel="noreferrer">リンク</a>

リファラー(Referrer)とは
HTTPリクエストヘッダーに含まれる、遷移元ページのURL情報。
アクセス解析に利用されるが、プライバシー保護の観点から送信しないことが望ましい場合がある。
noreferrer を指定すると、リンク先にこの情報が渡らなくなる。

両方指定する理由

属性 セキュリティ(opener無効化) プライバシー(リファラー非送信)
noopener 対応 非対応
noreferrer 対応 対応
両方指定 対応 対応

noreferrer だけでも noopener の効果を含むが、両方指定することで意図が明確になり、ブラウザ間の挙動差も吸収できる。

正しい実装

基本形

<a href="https://example.com" target="_blank" rel="noopener noreferrer">外部リンク</a>

JavaScriptで動的にリンクを開く場合

window.open を使う場合も noopener を指定する。

// ✅ noopenerを指定
window.open("https://example.com", "_blank", "noopener,noreferrer");
// ❌ 指定なし(window.openerが渡ってしまう)
window.open("https://example.com", "_blank");

Reactでの実装例

// 外部リンク用コンポーネント
const ExternalLink = ({ href, children }) => (
  <a href={href} target="_blank" rel="noopener noreferrer">
    {children}
  </a>
);

ESLintによる自動チェック

eslint-plugin-react を使えば、rel 属性の付け忘れを自動で検出できる。

{
  "rules": {
    "react/jsx-no-target-blank": "error"
  }
}

ブラウザの対応状況

2021年以降のモダンブラウザでは、target="_blank" を指定すると自動的に noopener が適用されるようになっている。

ブラウザ 自動 noopener 対応バージョン
Chrome 88+
Firefox 79+
Safari 12.2+
Edge 88+(Chromium版)

明示的に指定すべき理由

  • 古いブラウザ(IE、旧Edge)では自動適用されない
  • noreferrer は自動適用の対象外のため、プライバシー保護には明示的な指定が必要
  • コードレビュー時にセキュリティ対策の意図が伝わりやすい

対策が不要なケース

すべてのリンクに一律で付ける必要はない。以下のケースでは対策は不要。

  • 同一サイト内のリンク
    同じオリジンであれば window.opener を悪用されるリスクはない
  • target="_blank" を使わないリンク
    同一タブで遷移する場合は window.opener が発生しない

オリジン(Origin)は、URLの「スキーム(プロトコル)」「ホスト(ドメイン)」「ポート番号」の3つの組み合わせのこと

まとめ

  • target="_blank" には rel="noopener noreferrer" を必ず追加する
  • window.open で動的に開く場合も noopener を忘れない
  • モダンブラウザでは noopener が自動適用されるが、明示的な指定が推奨
  • ESLintなどのツールで付け忘れを防止する

参考サイト

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?