rel=”noopener noreferrer”はなぜ必要?target=”_blank”の安全対策を初心者向けに徹底解説

「外部リンクにtarget="_blank"を使うときは、rel="noopener noreferrer"も一緒に書いてね」と言われて、よくわからないままコピペしていませんか?

実は、target=”_blank”だけを使うと、セキュリティやパフォーマンス上のリスクが発生する可能性があるんです。WordPressなどのCMSでは自動的に付与されますが、手書きコーディングでは自分で正しく記述する必要があります。

この記事で分かること:

  • target=”_blank”に潜むセキュリティリスク「タブハイジャック」とは何か
  • rel=”noopener”とrel=”noreferrer”の違いと役割
  • 実務で使える正しい外部リンクの書き方と判断基準

この記事を読めば、なぜこの記述が必要なのか理論的に理解でき、自信を持ってコーディングできるようになります!

結論:target=”_blank”には必ずrel=”noopener”を付けよう

まず結論: 外部サイトへのリンクで新しいタブを開く場合、セキュリティとパフォーマンスのため、必ずrel=”noopener”を追加するのが現代の標準です。

すぐに使える安全な外部リンクの書き方:

  1. <!-- 基本形:noopenerは必須 -->
  2. <a href="https://example.com" target="_blank" rel="noopener noreferrer">
  3. 外部サイトへ
  4. </a>

重要なポイント3つ:

  • noopener: セキュリティリスク「タブハイジャック」を防ぐ(必須)
  • noreferrer: リンク元情報を隠す(プライバシー保護・任意)
  • 最新ブラウザ: 2021年以降は自動的にnoopenerが適用されるが、互換性のため明示的に書くのがベスト

target=”_blank”だけだと何が危険なのか?

window.openerによる「タブハイジャック」とは

target="_blank"で新しいタブを開くと、開かれた側のページから、元のページ(あなたのサイト)を操作できてしまうという問題があります。これを「タブハイジャック」と呼びます。

具体的な攻撃シナリオ:

  1. あなたのサイトに悪意のある外部リンクが設置される(または意図せず悪質サイトにリンク)
  2. ユーザーがそのリンクをクリックし、新しいタブで外部サイトが開く
  3. 外部サイト側でwindow.opener.locationを使い、元のタブ(あなたのサイト)を偽のフィッシングサイトに書き換える
  4. ユーザーが元のタブに戻ると、見た目が同じ偽サイトが表示されている
  5. ユーザーが個人情報を入力してしまう

攻撃コードの例(悪意のある外部サイト側):

  1. // 外部サイト(悪意のあるページ)のJavaScript
  2. if(window.opener) {
  3. // 元のタブ(リンク元)を偽サイトに書き換える
  4. window.opener.location = 'https://fake-phishing-site.com';
  5. }

注意: この攻撃は、信頼できるサイトにリンクしている場合でも、そのサイトが乗っ取られたり、意図せず悪意のあるスクリプトが埋め込まれた場合に発生する可能性があります。

パフォーマンスへの悪影響

セキュリティだけでなく、パフォーマンス面でも問題があります。

  • 同じプロセスで実行: target=”_blank”だけの場合、新しいタブは元のタブと同じブラウザプロセスで動作
  • リソースの競合: 外部サイトが重い処理をすると、元のタブ(あなたのサイト)も遅くなる
  • メモリ消費: 不要な参照が残り、メモリリークの原因になることも

rel="noopener"を付けると、新しいタブが別プロセスで開かれ、お互いに影響しないようになります。

rel=”noopener”とrel=”noreferrer”の違いを理解する

rel=”noopener”の役割

noopenerは、新しいタブから元のタブへのアクセスを遮断する属性です。

具体的な効果:

  • window.openernullになる
  • 外部サイトから元のページを操作できなくなる(タブハイジャック防止)
  • 別プロセスで開かれるため、パフォーマンスが向上
  • リファラー(参照元情報)は送信される
  1. <!-- noopenerのみの場合 -->
  2. <a href="https://example.com" target="_blank" rel="noopener">
  3. 外部サイトへ
  4. </a>
  5.  
  6. <!-- ↓外部サイト側では -->
  7. <!-- window.opener は null になる -->
  8. <!-- ただし、リファラーは送信される(どのページから来たかわかる) -->

rel=”noreferrer”の役割

noreferrerは、リンク元の情報(リファラー)を外部サイトに送信しない属性です。

具体的な効果:

  • HTTPリクエストヘッダーのRefererが送信されない
  • 外部サイトのアクセス解析で「どのページから来たか」がわからなくなる
  • noopenerの効果も自動的に含まれる(古いブラウザでも)
  • プライバシー保護に有効
  1. <!-- noreferrerのみの場合 -->
  2. <a href="https://example.com" target="_blank" rel="noreferrer">
  3. 外部サイトへ
  4. </a>
  5.  
  6. <!-- ↓外部サイト側では -->
  7. <!-- window.opener は null になる -->
  8. <!-- リファラーも送信されない(どこから来たか不明) -->

両方を組み合わせる理由

実務では「noopener noreferrer」を両方書くのが一般的です。理由は以下の通り:

理由 説明
ブラウザ互換性 古いブラウザではnoopenerが効かないことがあるが、noreferrerならnoopener効果も得られる
明示的な意図 「セキュリティ対策(noopener)」と「プライバシー保護(noreferrer)」の意図を明確に示せる
将来の保険 ブラウザの仕様変更に備え、両方書いておく方が安全
コードの可読性 何のために書いているかが他の開発者にも伝わりやすい
  1. <!-- ✅ 推奨:両方書く -->
  2. <a href="https://example.com" target="_blank" rel="noopener noreferrer">
  3. 外部サイトへ
  4. </a>

実務での正しい使い方と判断基準

外部リンクの基本パターン

実務でそのまま使える、状況別のコード例です。

  1. <!-- パターン1:一般的な外部リンク(最も多いケース) -->
  2. <a href="https://example.com" target="_blank" rel="noopener noreferrer">
  3. 外部サイトを見る
  4. </a>
  5.  
  6. <!-- パターン2:リファラーを送りたい外部リンク(提携先など) -->
  7. <a href="https://partner-site.com" target="_blank" rel="noopener">
  8. 提携サイトへ
  9. </a>
  10.  
  11. <!-- パターン3:同じタブで開く外部リンク -->
  12. <a href="https://example.com">
  13. 外部サイトへ(rel不要)
  14. </a>
  15.  
  16. <!-- パターン4:内部リンクを新しいタブで開く(PDFなど) -->
  17. <a href="/files/document.pdf" target="_blank">
  18. PDFを開く(rel不要)
  19. </a>

判断のポイント:

  • 外部サイト + target=”_blank”: rel="noopener noreferrer" を必ず付ける
  • 内部リンク + target=”_blank”: rel属性は不要(同じドメインなので安全)
  • 外部サイト + 同じタブ: rel属性は不要(window.openerが発生しないため)

アフィリエイトリンクの場合

アフィリエイトリンクでは、リファラー情報が計測に必要な場合があります。

  1. <!-- アフィリエイトリンク:noreferrerは付けない -->
  2. <a href="https://affiliate.example.com?id=12345"
  3. target="_blank"
  4. rel="noopener"> <!-- noreferrerは外す -->
  5. 商品を見る
  6. </a>

注意: ただし、アフィリエイトプログラムによっては独自のトラッキングIDで計測するため、noreferrerを付けても問題ない場合もあります。各サービスの仕様を確認しましょう。

SEO対策としてのrel属性

外部リンクには、SEO目的でrel属性を追加することがあります。

  1. <!-- 信頼できる外部サイトへのリンク -->
  2. <a href="https://trusted-site.com"
  3. target="_blank"
  4. rel="noopener noreferrer">
  5. 参考サイト
  6. </a>
  7.  
  8. <!-- 広告・スポンサーリンク -->
  9. <a href="https://sponsor.com"
  10. target="_blank"
  11. rel="noopener noreferrer sponsored"> <!-- sponsoredを追加 -->
  12. PR:スポンサー
  13. </a>
  14.  
  15. <!-- UGC(ユーザー生成コンテンツ)のリンク -->
  16. <a href="https://user-link.com"
  17. target="_blank"
  18. rel="noopener noreferrer ugc"> <!-- ugcを追加 -->
  19. ユーザー投稿リンク
  20. </a>

SEO関連のrel属性:

  • sponsored: 広告・スポンサーリンクであることをGoogleに伝える
  • ugc: ユーザー生成コンテンツ(コメント欄など)であることを示す
  • nofollow: リンク先の評価を渡さない(現在はsponsored/ugcの使用が推奨)

これらはスペース区切りで複数指定できます。

最新ブラウザの自動保護機能について

2021年以降の変化

実は、Chrome 88(2021年1月)以降、主要ブラウザではtarget=”_blank”に自動的にrel=”noopener”が適用されるようになりました。

主要ブラウザの対応状況:

  • Chrome: v88以降(2021年1月〜)自動適用
  • Firefox: v79以降(2020年7月〜)自動適用
  • Safari: v12.2以降(2019年3月〜)自動適用
  • Edge: v88以降(2021年1月〜)自動適用

それでもrel=”noopener”を書くべき理由

最新ブラウザでは自動保護されますが、実務では明示的に書くことが推奨されます。

明示的に書くべき理由:

  1. 古いブラウザ対応: まだ古いバージョンを使っているユーザーも存在する
  2. コードの意図を明確にする: セキュリティ対策をしていることが他の開発者にも伝わる
  3. 将来の保険: ブラウザの仕様変更に備える
  4. 社内規約・コーディング規約: 多くの企業やプロジェクトで明示が必須
  5. リンターやバリデーター: HTMLチェックツールで警告が出ることがある
  1. <!-- ❌ 最新ブラウザでは動作するが、非推奨 -->
  2. <a href="https://example.com" target="_blank">
  3. 外部サイトへ
  4. </a>
  5.  
  6. <!-- ✅ ベストプラクティス:明示的に書く -->
  7. <a href="https://example.com" target="_blank" rel="noopener noreferrer">
  8. 外部サイトへ
  9. </a>

結論: 「最新ブラウザなら自動で安全」という知識は持ちつつ、実務では必ず明示的に書くようにしましょう。

よくあるつまずきポイントと解決法

1. rel属性の書き方が間違っている

  1. <!-- ❌ 悪い例:カンマ区切り -->
  2. <a href="https://example.com" target="_blank" rel="noopener,noreferrer">
  3.  
  4. <!-- ❌ 悪い例:複数のrel属性 -->
  5. <a href="https://example.com" target="_blank" rel="noopener" rel="noreferrer">
  6.  
  7. <!-- ✅ 良い例:スペース区切り、1つのrel属性 -->
  8. <a href="https://example.com" target="_blank" rel="noopener noreferrer">

ポイント: rel属性の値はスペース区切りで複数指定します。カンマや複数のrel属性はNGです。

2. 内部リンクにもrel属性を付けてしまう

  1. <!-- ❌ 不要:内部リンクには不要 -->
  2. <a href="/about.html" target="_blank" rel="noopener noreferrer">
  3. 会社概要
  4. </a>
  5.  
  6. <!-- ✅ 正しい:内部リンクならrel不要 -->
  7. <a href="/about.html" target="_blank">
  8. 会社概要
  9. </a>

理由: 同じドメイン内のリンクなら、window.openerがあっても安全です(自分のサイトなので)。rel属性は外部リンクにのみ必要です。

3. target=”_blank”を使わない方がいい場合もある

実は、必ずしもtarget=”_blank”を使う必要はありません。UX(ユーザー体験)の観点から、使わない方が良い場合もあります。

target=”_blank”を避けるべきケース:

  • モバイル: タブが増えすぎて管理が大変になる
  • 短い記事・ページ: 戻るボタンで十分な場合
  • ユーザーの選択を尊重: ブラウザのCtrl+クリック(新しいタブで開く)に任せる
  1. <!-- 場合によってはtarget="_blank"なしでもOK -->
  2. <a href="https://example.com">
  3. 外部サイトへ(同じタブで開く)
  4. </a>

target=”_blank”を使うべきケース:

  • フォーム入力中に参考資料を見せたい場合
  • PDFやダウンロードファイル
  • 長文記事の参考リンク

実務チェックリスト

外部リンクを実装する前に、このチェックリストで確認しましょう。

  • target=”_blank”を使う場合、rel=”noopener noreferrer”を付けたか
    → セキュリティとプライバシー保護のため必須
  • 内部リンクには不要なrel属性を付けていないか
    → 同じドメインならrel属性は不要
  • アフィリエイトリンクの場合、noreferrerの要否を確認したか
    → トラッキングに影響する可能性があるため、仕様を確認
  • rel属性の書き方は正しいか(スペース区切り)
    → カンマ区切りや複数のrel属性はNG
  • そもそもtarget=”_blank”が本当に必要か検討したか
    → UXの観点から、使わない方が良い場合もある
  • 外部リンクであることをユーザーに伝えているか
    → アイコンや「別タブで開く」などのテキストを追加するとより親切

よくある質問

Q1. WordPressやCMSが自動で付けてくれるなら、手書きでは不要ですか?

A. 手書きコーディングでは必ず自分で書く必要があります。WordPressは「Gutenbergエディター」や「クラシックエディター」で外部リンクを挿入すると自動的に付与してくれますが、HTMLを直接書く場合は自動では追加されません。また、古いCMSやカスタムコードでは付与されないこともあるため、必ず確認しましょう。

Q2. rel=”noopener”だけでも十分ですか?noreferrerは必須ですか?

A. セキュリティ面ではrel=”noopener”だけで十分です。ただし、古いブラウザ対応やプライバシー保護の観点から、両方書くのが一般的です。noreferrerを付けることで:

  • 古いブラウザでもnoopener効果が得られる
  • リンク元情報を隠せる(プライバシー保護)
  • コードの意図が明確になる

という利点があります。

Q3. JavaScriptでwindow.openを使う場合はどうすればいいですか?

A. JavaScriptでも同様に対策が必要です。

  1. // ❌ 危険:window.openerが残る
  2. window.open('https://example.com');
  3.  
  4. // ✅ 安全:第3引数でnoopenerを指定
  5. window.open('https://example.com', '_blank', 'noopener,noreferrer');
  6.  
  7. // または、開いた後にopenerを無効化
  8. const newWindow = window.open('https://example.com');
  9. newWindow.opener = null;

Q4. Google Analyticsのトラッキングに影響はありますか?

A. Google Analyticsのトラッキングには影響しません。rel=”noreferrer”を付けても、Google Analytics側では自分のサイト内の行動(どのリンクをクリックしたか)は計測できます。影響を受けるのは「リンク先のサイト」のアクセス解析で、「どこから来たか(リファラー)」がわからなくなるだけです。

Q5. すべてのリンクをチェックするのは大変です。効率的な方法はありますか?

A. 以下の方法で効率化できます。

  • エディタの検索機能: target="_blank"で検索し、rel属性があるか確認
  • HTMLバリデーター: W3Cのバリデーターで警告が出る
  • ブラウザ拡張機能: リンクチェッカーで一括確認
  • コーディング規約: チーム内でテンプレートやスニペットを用意
  • JavaScriptで一括修正: 既存サイトなら、JSで自動付与する方法もある
  1. // 既存サイトでの一括修正例(応急処置)
  2. document.querySelectorAll('a[target="_blank"]').forEach(link => {
  3. const rel = link.getAttribute('rel') || '';
  4. if(!rel.includes('noopener')) {
  5. link.setAttribute('rel', 'noopener noreferrer ' + rel);
  6. }
  7. });

注意: JavaScriptでの修正は応急処置です。HTMLを直接修正するのが根本的な解決策です。

まとめ

target="_blank"で外部リンクを開く場合、rel=”noopener noreferrer”を必ず付けるのが現代のWeb制作の常識です。この記事のポイントをおさらいしましょう。

  • セキュリティリスク: target=”_blank”だけだと「タブハイジャック」攻撃のリスクがある
  • noopenerの役割: window.openerを無効化し、セキュリティとパフォーマンスを向上
  • noreferrerの役割: リファラー情報を隠し、プライバシーを保護(古いブラウザ対応にも有効)
  • 実務の基本: 外部リンク + target=”_blank” = rel=”noopener noreferrer”
  • 最新ブラウザ: 自動で保護されるが、明示的に書くのがベストプラクティス

今日から実践できること:

  • 既存のコードでtarget="_blank"を検索し、rel属性があるかチェック
  • エディタにスニペット登録して、自動で正しいコードが挿入されるようにする
  • チーム内でコーディング規約を確認・共有する

次のステップ:

  • HTMLのセキュリティ全般(XSS、CSRFなど)についても学ぶ
  • アクセシビリティの観点から、外部リンクにアイコンやテキストを追加する方法を学ぶ
  • JavaScriptのセキュリティベストプラクティスを理解する

最初は「なんとなくコピペ」していたrel="noopener noreferrer"も、その意味を理解すれば、自信を持って実装できるようになります。セキュリティは小さな積み重ねが大切です。この記事で学んだ知識を、ぜひ実際のコーディングで活かしてください!

スポンサーリンク
スポンサーリンク