はじめに
皆さんはセキュリティ対策行っていますでしょうか?
正直、自分はちゃんと理解してセキュリティ対策を行なっているとは言えないです。
そこで、大変なことになる前に有名なサイバー攻撃や脆弱性、セキュリティに対する知識を身に付けて備えていきたいと思います。
target="_brank"
今回自分が脆弱性についてまとめようと考えたきっかけの一つです。
普段の業務で何気なく使っているtarget="_brank"
も実は脆弱性があるみたいです。
今まで何度も使ってきたのに全然知りませんでした…
target="_brank"
はaタグ内で使用することで、リンク先を別タブで開くようにすることができますが、どうやらこの別タブでリンク先を開いた後が危ないみたいです。
なんの対策もせずにtarget="_brank"
単体で使用してしまうとタブナビング攻撃
という攻撃を受ける可能性があります。
タブナビング攻撃とは、現在見ていない非アクティブなタブのページを勝手に別のページに飛ばす攻撃のことです。
例えば、裏で別のログインページに飛ばして、パスワードなどを入力させて個人情報を引き抜いたりするみたいです。恐ろしいですね
target="_brank"
は遷移前の元ページをwindow.opener
オブジェクトとして参照することができるらしく、それを使って元ページを別のページへ飛ばしてしまうみたいです。
その仕組みの例としてこちらのサイトがとてもわかりやすかったです。
window.opener.location.href = url;
をサブウィンドウからメインウィンドウを操れていますね。
対処法
こちらはaタグのrel属性にnoopener
、noreferrer
オプションをつけるだけで対策できます。安心ですね。
noopener
は遷移先のページからwindow.opener
を参照できなくします。これでURLなど書き換えられずに済みます。
ただ、一部のブラウザではサポートしていなかったするみたいです。そこで二つ目のnoreferrer
です。
noreferrer
を使うことで元ページの情報を取得することができなくなり、どこから訪問してきたのか特定ができない、参照元がない状態にすることができます。
これら二つを使うことで対応できるブラウザの幅を広げ完全に対策することができます。
また、これらを使うことで元ページと遷移後のページが別スレッドで処理されるため、遷移後ページの重い処理が元ページに影響を与えにくくなり、パフォーマンスの向上も見込めます。
今後aタグを使用するときはnoopener
、noreferrer
を指定するのがよさそうです。
追記
aタグを使うときはnoopener
、noreferrer
を指定するのがよさそうと書きましたが2024年現在では指定する必要はあまりないみたいです。
主要ブラウザであるSafari、Firefox、Chrome、Edgeはaタグにtarget="_brank"
が指定された時点で、rell="noopener"
と同じ挙動をするみたいです。
また、サイト内リンクにnoreferrer
を指定したりすると、アクセス解析に支障をきたしてしまい、逆に良くない場合があるみたいです。外部サイトに対して、情報を渡したくない時のみ指定するのがよさそうです。
XSS(クロスサイトスクリプティング)
続いてはXSS(クロスサイトスクリプティング)についてです。
XSSとは攻撃者が悪意のあるコードを、脆弱性のあるサイトのフォームや掲示板などに仕込み、訪れたユーザーがアクセスするたびに不正なスクリプトを実行する攻撃です。
これについては少し前から知っていました。そのきっかけは今年の4月ごろにSNSなどで話題になっていた日本医師会の適正体重計算サイトです。(もちろん現在は修正されています。)
このサイトは自身の身長を入れることで、適正体重がわかるというシンプルなものでした。
なぜこのサイトがXSSの危険性があったのかというと、適正体重を計算するのにeval関数
を使っていたためです。
eval関数とは、引数に指定した文字列をJavaScriptプログラムコードとして評価・実行する機能をもつ関数です。
そんなeval関数を使ってしまったため、身長の欄にJavaScirptのコードを入力すると実行することができてしまいました。
ただ、幸いなことに今回の事例ではローカルでしか動いていないので、他ユーザーに影響を及ぼすXSSにはなっていませんでした。
このように脆弱性を突かれて悪意のあるコードを仕込まれてしまう可能性があります。
対処法
入力できる値を制限することで対処することができます。現在の日本医師会のサイトはこの対処法を使っていそうです。
数字のみ入力できるようになっていて、他のアルファベットなどは入力できないようになっていました。
また、特別な記号にエスケープ処理を行うのも効果的です。
悪意のあるコードを実行するためには<
、>
や&
などの記号が必要です。そこで、これらの記号を文字そのものとして処理することでスクリプトを無害化させます。
あとはeval関数のような危険な関数は使用しないようにしましょう。
今後フォームなど実装する時はより一層気をつけていきたいです。
CSRF(クロスサイトリクエストフォージェリ)
先ほどのXSSと似た名前の攻撃ですね。
こちらもサイトの脆弱性をついてくる攻撃ですが、CSRFはユーザーのセッション管理の脆弱性をついてきます。
アプリやSNSでログインした状態を利用して個人情報を抜き取ったり、アカウント情報の変更や不正な入出金、購入をしてきます。
ユーザーがログアウトをせずに悪意のあるサイトを開いてしまうと、ユーザーの認証情報を利用して不正なリクエストを送信されてしまいます。ログインしている状態なので元のサイトは正当なリクエストと誤認し、処理を実行してしまうという流れです。
対処法
一般的な対処法はCSRFトークンなどを使う方法みたいです。
サーバー側からランダムに生成されたトークンを取得し、それをログイン情報などと一緒にセッションに保存します。簡単にいうと合言葉のようなものです。
ユーザーがサイト内で何か行うたびにトークンを送信します。
サーバー側は送信されたトークンを受け取り、以前発行したトークンと一致するかを確認します。一致すれば正当なリクエストと判断し処理が行われます。
このトークンはユーザーが正規のウェブサイトにログインした時に生成され、サーバー側で管理されるため攻撃者はトークンを取得することができません。
そのため、サーバー側がトークンが一致しているか判断するときに弾かれて、不正なリクエストを送信されるのを阻止することができます。
まとめ
今まで何度も使ってきたtarget="_brank"
に脆弱性があったり、聞いたことのない攻撃について知ることができました。脆弱性やセキュリティについてはあまり意識せずコーディングをしてきましたが、今後はよりセキュリティに対して意識を高め、使用する技術に本当に脆弱性がないのか確認したり、これまで世の中で起きた事例を調べて攻撃を受けないように対策していきたいと思います。
参考サイト
最後に参考にさせていただいたサイトを載せておきます。最後まで見ていただきありがとうございました!