新しいウィンドウを開く際の考慮事項とセキュリティリスク
はじめに
ウェブ開発において、リンクをクリックした際に新しいウィンドウやタブを開くことはよくあります。しかし、この動作にはセキュリティリスクやユーザーエクスペリエンスの観点から問題が指摘されています。今回は、このリスクとその対策について解説し、実装時の注意点を説明します。
新しいウィンドウを開く必要性の再検討
新しいウィンドウやタブを開く理由には、ユーザーが現在のページを保持したまま別の情報にアクセスできることが挙げられます。しかし、これがユーザーエクスペリエンスを悪化させる可能性もあります。特に、複数のタブが開かれることでユーザーが混乱したり、セッションの管理が難しくなったりするリスクがあります。そのため、本当に新しいウィンドウを開く必要があるかをまず再検討することが重要です。
新しいウィンドウを開く際のセキュリティリスク
target="_blank"
のセキュリティリスク
新しいウィンドウを開くために一般的に使用されるのが、target="_blank"
属性です。しかし、MDNのドキュメントでも指摘されているように、target="_blank"
にはセキュリティリスクがあります。具体的には、リンク先が元のページを制御できる可能性があり、これを「Tabnabbing」と呼びます【MDN Web Docs】。
Tabnabbingのリスクとサンプルコード
Tabnabbingは、現代のウェブセキュリティにおいて最も深刻な脅威の一つとされています。 この攻撃手法は、悪意のあるリンク先がユーザーの意図しない操作を強制することで、元のタブの内容を巧妙にすり替えるものです。結果として、ユーザーは見た目は変わらないが実際にはフィッシングサイトにリダイレクトされたページに誘導され、そこに機密情報を入力してしまう可能性があります。
この種の攻撃は、ユーザーがリンクをクリックした後、信頼できるサイトだと錯覚させることで進行するため、特に狡猾です。攻撃者は元のタブのコンテンツを操作し、例えばログインページや支払いページなど、見た目は正規のサイトにそっくりなフィッシングページに置き換えます。そのため、ユーザーは自身が攻撃に遭っていることに気づかず、個人情報や認証情報を攻撃者に提供してしまうリスクが極めて高くなります。
Tabnabbingについて言われ始めた時期:
Tabnabbingは、2009年にウェブセキュリティ研究者のAza Raskinによって初めて公に指摘されました。彼が発表したこの脅威に関するブログ記事をきっかけに、広く認知されるようになりました【Aza Raskin's blog】。
ブラウザが対応し始めた時期:
Tabnabbingが広く認識された後、ウェブ開発者やブラウザ開発者の間でセキュリティ強化が求められるようになり、2015年頃から主要なブラウザ(Chrome、Firefoxなど)でrel="noopener"
のサポートが導入され始めました。この属性は、リンク先が元のページを制御できないようにするためのものです。
以下に、元のサイトと攻撃者のサイトのサンプルコードを示します。
元のサイトのコード(被害者のサイト)
以下は、target="_blank"
を用いて信頼できるサイトへリンクするコードです。このリンクをクリックすると、新しいタブでリンク先が開きます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>元のサイト</title>
</head>
<body>
<h1>元のサイト</h1>
<p>以下のリンクをクリックすると、新しいタブで開きます。</p>
<a href="https://example.com" target="_blank">信頼できるサイトへのリンク</a>
</body>
</html>
攻撃者のサイトのコード(攻撃側のサイト)
攻撃者のサイトは、新しいタブが開かれた後に元のタブの内容をフィッシングサイトにリダイレクトします。以下は、そのためのシンプルなスクリプトです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>悪意のあるサイト</title>
<script>
setTimeout(function() {
if (window.opener) {
window.opener.location.href = "https://phishing-site.com";
}
}, 3000); // 3秒後に元のタブのURLを変更する
</script>
</head>
<body>
<h1>悪意のあるサイトです</h1>
</body>
</html>
このコードの流れでは、ユーザーが元のサイトでリンクをクリックし、新しいタブが開かれた後、元のタブの内容が攻撃者のフィッシングサイトに変更されます。これにより、ユーザーは意図せず元のサイトだと思ってフィッシングサイトに誘導され、機密情報を入力してしまう可能性が非常に高くなります。
Tabnabbingが起きやすいサイト構造
Tabnabbingは特に以下のようなサイト構造で起きやすいです。
-
投稿可能なサイト: ユーザーが自由にコンテンツを投稿できるプラットフォーム、例えば掲示板やコメント機能があるブログなどでは、ユーザーがリンクを投稿することができます。攻撃者はこれを利用して、
target="_blank"
を含む悪意のあるリンクを投稿し、他のユーザーを攻撃します。 -
URLを含められるフォームやプロフィール: 一部のウェブサイトでは、ユーザーがプロフィールやフォームにURLを含めることができる場合があります。これも攻撃者が利用しやすい場所です。
-
ユーザー生成コンテンツを表示するサイト: フォーラム、SNS、オンラインマーケットプレイスなど、ユーザー生成コンテンツが中心となるサイトでは、攻撃者が悪意のあるリンクを埋め込むリスクが高まります。
安全な実装方法
rel="noopener noreferrer"
の利用
どうしても新しいウィンドウを開く必要がある場合、rel="noopener noreferrer"
属性を追加することでTabnabbingを防ぐことができます。MDNでも推奨されているこの属性は、リンク先が元のページを制御するのを防ぐ役割を果たします。
実装例:
<a href="https://example.com" target="_blank" rel="noopener noreferrer">信頼できるサイトへのリンク</a>
これにより、新しいウィンドウを開きつつ、セキュリティリスクを低減することができます。
ブラウザのポップアップ判定基準
ポップアップブロッカーの動作
ブラウザは、ポップアップがユーザーの操作に基づいているかどうかを判定します。MDNのドキュメントによれば、ユーザーが直接操作した後、例えばクリック後5秒以内にポップアップが発生した場合、それはユーザーの操作と見なされ、ポップアップブロッカーによってブロックされる可能性が低くなります【MDN Web Docs】。
また、Chromiumプロジェクトでも、この5秒という時間はkActivationLifespan
として定義されており、以下のようにコードが実装されています。
constexpr base::TimeDelta kActivationLifespan = base::TimeDelta::FromSeconds(5);
【[Chromium GitHub
Repository](https://github.com/chromium)】。これにより、クリック後5秒以内のポップアップはユーザー操作として扱われることが明確化されています。
まとめ
セキュリティとユーザーエクスペリエンスのバランス
新しいウィンドウを開く動作を実装する際は、その必要性を慎重に検討し、セキュリティ対策を必ず実施することが重要です。また、ユーザーエクスペリエンスを考慮し、不要なポップアップの作成を避けることで、安全で快適なウェブ体験を提供できます。
追記
観点を一つ追加です。
各種ブラウザはユーザーの操作と判断すればポップアップをブロックしないようです。ユーザーの操作と判断できない場合にブロックしてきます。そういった観点で考えると良いですね。
Discussion