aタグのrel属性!Tabnabbing回避からSEOまで

2020/12/16に公開

始め

aタグの存在はコーディング勉強始めたぐらいから知ってましたが、rel属性については最近初めて知りました。なんで今まで分からなかったんだろう…と思いましたので一回整理します。


1. Tabnabbing

1-1. aタグのtarget属性

ウェブサイトでハイパーリンクをクリックすると現在見てたタブで開くか、新しいタブで開くかのどちらかの場合が多いと思います。その動きの設定はにも記載されている通り、target属性で指定できます。

aタグのtarget属性(MDNのaタグドキュメントから)

  • _self: 現在の閲覧コンテキストです。 (既定値)
  • _blank: ふつうは新しいタブですが、新しいウィンドウを使用するようにブラウザーを設定できます。

この他にもありますが、よく使われているものはこの2つかと思いますので一旦2つだけ持ってきました。デフォルト値は_selfなのでtarget属性自体を設定しなかったら自動的にtarget="_self"になります。

1-2. New Tabを通じた攻撃

いままで話したtarget="_self"の隙間に潜り込むTabnabbingという攻撃について説明させていただきます。

例えば、luvmini.example.comというサイトを見ているとしましょう。

そのサイトにはother.example.comに飛べる外部リンクがあります。ユーザーはそのリンクをクリックし、other.example.comを新しいタブで開きました。

ここから大事ですが、その新しく開いたother.example.comタブにはwindow.openerという属性が存在しますMDNドキュメントによると、window.openerは現在のウィンドウを開いたウィンドウへの参照を返すやつのようです。つまり、新しく開いたタブから親タブ(既存のタブ)を参照できるということです。

これの何がまずいかと言うと、ユーザーが新しいタブを見てる間に誰かが悪意を持って既存のタブを操作できるという意味です。

例えの続きをしましょう。ユーザーがother.example.comを見ている間に、悪い人がJSを用いて親タブluvmini.example.comのlocationをluvmimi.example.comというフィッシングサイトに変えました。見た目も前もって同じように作っといて、アドレスもほぼ同じなのでパット見違うサイトだと分からりにくいです。

そしてユーザーがother.example.comを見終わった後に変更されたluvmimi.example.comに戻ります。フィッシングサイトなので当たり前にログインされてない状態ですが、ユーザーは「あれ?ログアウトされちゃったんかな」と思ってIDとパスワードを入力します。

そしてフィッシングサイトのluvmimi.example.comは、ユーザーが入力したIDとパスワードを悪い人のサーバーに送信して本当のサイトであるluvmini.example.comにリダイレクトさせて逃げます。ユーザーは普通にログインしたと思うだけで、被害を自覚することも難しいです。

これがTabnabbingという情報を盗む攻撃です。2010年にセキュリティー専門家Aza Raskinがつけた名前ですから結構知以前からあったフィッシングのようですね。この手の攻撃はSNSなどのコミュニティやメールでよく起きます。

2. rel="noopener"

2-1. セキュリティーについて

Tabnabbingの危険を防ぐためにrel=noopener属性が追加されました。rel=noopenerをつけると、新しいタブを既存タブと違う、別途スレッドで開くことができます

これの何が良いかというと、別途スレッドで動くので新しいタブから既存タブを参照できなくなります

メールボックスに溜まってECサイトからのプロモーションメールで試してみたら、window.openernullになってました(韓国のサイトで試したのでハングルが見えますね)。これだったらJSで操作しようとしてもUncaught TypeErrorが発生するので安全だと思います。

aタグに関するMDNドキュメントtarget説明にもこのような注釈があります。

注: 新しいブラウザー (例えば Firefox 79 以降) では、 target="_blank" を <a> 要素に設定すると、暗黙に rel の動作を rel="noopener" と設定したのと同様になります。

Tabnabbingの攻撃を防ぐためにこのようなバージョンアップをしたのが分かります。

2-2. パフォーマンスについて

また、noopenerパフォーマンス的にも利点があります

元々は新しいタブと既存タブが同じスレッドで動くので、新しいタブで開いたサイトがものすごく重かったら既存タブまで遅くなります。

しかし、別途スレッドだったら新しいタブのサイトがどれだけ重くても既存タブには影響がないので、既存タブが遅くなる心配がないです。

2-3. ブラウザのサポート状況

ここで大事なのはブラウザがこの属性をサポートしてるかどうかですね。Can I useで確認してみたらモーダンブラウザは大体サポートしているようです。しかし、Firefoxは2017年にリリースされた52バージョンからサポートしてることを考えると、そこまでは安心できないかもしれません。IEは未だにサポートしてない

3. rel="noreferrer"

3-1. セキュリティーについて

noreferrerというものもまります。aタグにrel=noreferrerをつけると、HTTPヘッダーから参照情報を削除することで参照情報が渡されることを塞げます。つまり、新しいタブから既存タブの情報を削除して漏れないようにすることでしょう。noreferrernoopenerも新しいタブからwindow.openerにアクセスするとnullが来るので、結果的には同じことをやってますが、原理には違いがあります。

  • noopenerは新しいタブを別途スレッドに完全に分離させることで既存タブを参照できなくする
  • noreferrerは同じスレッドで新しいタブ開くけど既存タブの情報を渡さないことで既存タブを参照できなくする

3-2. SEOについて

また、noreferrerについて調べるとSEOに悪影響があるかもという心配も見つけられますが、noreferrerSEOに直接的な影響を与えることはありません

グーグルのWebmaster Trends AnalystであるJohn Muellerが「noopenernoreferrerはSEOに影響がありますか?」と聞かれてシンプルに「nope」と答えてるツイッターもありました。

しかし、グーグルアナリティクスレポートを混乱させるリスクはあります

グーグルアナリティクスを使うとユーザーがどうやってウェブサイトに入ったかを分析できます。その種類には、

  • referral(他のサイトが載せたリンクを通じて入った場合)
  • Direct(url入力などで直接入った場合)
  • Organic Search(検索エンジンの検索で入った場合)
  • Social(SNSから入った場合)

などなど、色々なものがあります。aタグから他のサイトに遷移した場合はreferralに当てはまりますが、noreferrerをつけるとDirectに分類されてしまいます

これは分析レポートに事実ではないことを含ませるので、あまりよろしい状況ではありません。という訳で、このテーマについて詳しく話している他のブログでも内部リンクではrel=”noreferrer”を使わないように!と言ってました。

Definitely do not use the rel=”noreferrer” attribute on internal links, it can mess up with your Google analytics reports.
内部リンクでrel=”noreferrer”属性を使うことは絶対にしないようにしましょう。グーグルアナリティクスのレポートで混乱することがあります。

3-3. ブラウザのサポート状況

noreferrernoopenerより古いのバージョンのブラウザもサポートしています。同じくCan I useで確認できます。

aタグに関するMDNドキュメントtarget説明にはTabnabbingを防ぐためにrel="noreferrer"をつけるようにと書いています。

注: targetを使用する際は、window.openerAPIの悪用を避けるためにrel="noreferrer"を追加してください。

おそらくnoreferrerのほうがもっと古いブラウザもサポートしているからMDNではnoreferrerの方をおすすめしていると思われます。一般的にはrel="noopener noreferrer"のように両方つける方法が多く採用されていると感じですね。

4. rel="nofollow"

rel属性の中にはnofollowというものもあります。aタグにこれをつけたらウェブクローラーがそのリンクを収集できなくします。つまり、そのリンクをSEOに反映されないようにするということでしょう。愚かな私は最初に「え、これ要る?」と思いましたが、もちろん要ります。

4-1. 有料リンク

有料リンクはSEOペナルティの対象です。お金払ってリンクを買って検索結果を騙す場合があるからのりゆうのようです。有料リンクに対するGoogleの方針は公式ドキュメントでもっと詳しく確認できます。

しかし、有料リンクは必ず検索結果操作の目的だけで使われてるわけでもありません。例えば、ある商品の広告をしたい場合なでも有料リンクを含みます。この部分に関しては上貼ったドキュメントでも言及しています。

すべての有料リンクが Google のガイドラインに違反するわけではありません。リンクの売買も、検索結果の操作でなく宣伝を目的として行われる限り、ウェブ上での通常の経済活動となります。広告として購入したリンクでは、そのことを明示する必要があります

この「広告だと明示する」方法がrel=nofollowをつけることです。そうしたら有料リンクを入れてもSEOペナルティを受けなくなります。

4-2. 他のユーザーによって生成されるコンテンツ

SEOに関するGoogleのドキュメントにこういう部分があります。

他のサイトにリンクすると、自分のサイトに対する評判の一部を別のサイトに与えることになります。ときどき、このことを利用しようとして、別のサイトのコメント欄や掲示板に自分のサイトへのリンクを追加するユーザーがいます。そのため、あるサイトに否定的に言及するとともに、自分のサイトへの評判をそのサイトには与えたくないと考える場合もあるでしょう。

不特定多数のユーザーが作成できるコメント欄や掲示板などは、他人が自分のサイトの評判を上げるためにリンクを投稿する可能性が高いです。この時rel=nofollowを使うと、Googleに自分のページの評価をリンク先のページに渡さないようにと伝えることができます

4-3. 埋め込み

埋め込みで他のサイトのウィジェットリンクを乗せることは結構あると思います。その中で、埋め込みはしたいのに埋め込み先のサイトに私のサイトには載せたくない場合もあるかもしれません。こういう場合もrel=nofollowを使ったらSEOに反映されないので、安心して埋め込みできます。

4-4. nofollowの進歩

nofollowは2005年生まれた属性で、今まで説明した通りリンクをSEO評価対象から外せることに使われてました。確かにnofollowは有用ですが、本来なら評価対象にすべきリンクまで全部対象外にしてしまうなどの問題もあがって来ました。この問題を解決するためにGoogleは2019年新しい方針を発表します。

  • rel="sponsored"
    : 広告や有料プレースメントのリンク(一般に「有料リンク」と呼ばれます)
  • rel="ugc"
    : コメントやフォーラム投稿など、ユーザー作成コンテンツ(UGC)
  • rel="nofollow"
    : リンクにその他の適切な値がなく、そのリンクとサイトを関連付けたくない場合、またはリンク先のページをサイトからクロールさせないようにする場合

まずは全部nofollowでやってたのを目的ごとにsponsoredugcnofollowの3つに分けました。そして他の変化もあります。

When nofollow was introduced, Google would not count any link marked this way as a signal to use within our search algorithms. This has now changed. All the link attributes -- sponsored, UGC and nofollow -- are treated as hints about which links to consider or exclude within Search. We'll use these hints -- along with other signals -- as a way to better understand how to appropriately analyze and use links within our systems.

簡略にいうと、今まではnofollowをつけたリンクは完全にSEO対象外にしてたけど、今(2019.09.05)からはヒントとして収集するかもしれないという内容です。公式ドキュメントにもかいてありますが、既存のnofollowを全部この3つ分けて変更する必要はないものの、これからGoogleはこの3つを分けて使うことをおすすめするというスタンスです。


終わり

最初に書き始めたときは軽い気持ちだったのに、深ぼれば深ぼるほど内容が無限に出てきてびっくりしました(特にSEO周りが)。この記事は本当に足指一本入れたぐらい浅い内容ですが、私みたいな初心者の方々に役に立ったらいいなと思います。

GitHubで編集を提案

Discussion