Javascriptのwindow.openerをご存知でしょうか?
MDN web docsの説明文では以下の様に説明されております。
現在のウィンドウを開いたウィンドウへの参照を返します。
読んでもつまりどういうこと…?となってしまうかもしれません。
ざっくり言うと、新しく開いた子ウインドウ側から親ウインドウを操作できてしまうということです。
操作できてしまうとどんな不都合が起きるかというと、
例えば外部リンク(別ウインドウで開く)をサイトに設置してそれを開いたとします。
この場合外部リンクを設置したサイトが親ウインドウ側になります。
開いた外部リンクが子ウインドウとなります。
そして子ウインドウ側にjavascriptが仕込まれており親ウインドウのページを危険なサイトへ誘導させるといったことも可能になるわけです。
これは子ウインドウが発生することが条件ですので必然的にtarget=”_blank”を設置しているリンクが該当します。
target=”_blank”が設置されていないリンクに関してはそのウインドウのまま遷移するため問題ありません。
対策方法
Window.openerに対する対策方法は簡単です。
aタグにrel=”noopener”あるいはrel=”noopener noreferrer”の属性を追加するだけです。
たったこれだけで対策が可能となります。
noopenerについてはそのままの意味でopenerを受け付けないということになります。(No!Opener ですね)
noreferrerについてはリンク先の情報をリンク先に送らない様にするといった設定になります。
2つつけても良いですが、noreferrerについてはアフィリエイトなどを使用していた場合にどのページからなのかが参照できなくなってしまう可能性があるため状況に応じて使用するといった感じでしょうか。
もちろん直接都度書いてもいいですが、いちいち表記を追加するのは大変だと思いますし、なにかの拍子に抜けてしまうといったこともあるかと思います。
そこで、aタグを読み取ってそこにtarget=”_blank”があったらrel=”noopener”を追加するというfunctionを作成します。
function SafetyBlank() {
const elementA = document.querySelectorAll('a');
elementA.forEach((element) => {
if(element.hasAttribute('target') === false) {
return;
}
if(element.getAttribute('target') !== '_blank') {
return;
}
element.setAttribute('rel','noopener');
});
}
SafetyBlank();
※上記はES6表記を使用しておりますのでそのまま使用するとIE等一部ブラウザで動作しないためご注意ください。その場合はコンパイルして使用することをおすすめします。
これは何をやっているかと言うと、
elementAという変数を定義してページ上のaタグをまとめて取得します。
さらにforEachで取得したaタグの数だけ個別にtarget=”_blank”があるかの判定を行います。
そしてtarget=”_blank”があるaタグに関してはrel=”noopener”の記述をJavascript側で動的に追加するといった流れです。
これを読ませておけば特に追加で記述する必要もないのでおすすめです!
是非活用してみてください。