Flatt Security Blog

株式会社Flatt Securityの公式ブログです。プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

株式会社Flatt Securityの公式ブログです。
プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

開発者が知っておきたい「XSSの発生原理以外」の話

f:id:flattsecurity:20220224211724p:plain

はじめに

こんにちは。株式会社Flatt Securityのセキュリティエンジニアの冨士です。

本稿では、XSS(クロスサイトスクリプティング)が攻撃に用いられた時のリスクの大きさを紹介していきます。以降はクロスサイトスクリプティングをXSSと記載していきます。

XSSはセキュリティエンジニアならもちろん、開発を行っているエンジニアの多くの方が知っている脆弱性です。ですが、私はWebアプリケーションの脆弱性診断を行ってきた経験の中で多くのXSSを目にしてきましたし、依然として検出率の多い脆弱性の一つだと感じています。

その認知度や、一般的な対策方法のハードルの低さ(設計や仕様によっては対策工数が大きい場合もありますが)にも関わらずXSSの検出率が多いのは、直感的にリスクがわかりづらく、アラートをあげるだけの紹介が多いことが一つの要因ではないかと考えています。

すなわち、興味範囲が「どのようにして第三者のドメインでJavaScriptを実行させるか」という脆弱性の発生原理だけに留まっており、「どのようなJavaScriptが動作し、どのようなリスクが生まれるか」というサービス開発者やサービスユーザーの目線が欠けてしまいがちだと思うのです。

また、脆弱性診断の報告書ではXSSによるリスクの記述も行われますが、やはり、どのような形で攻撃が行われるかはわかりづらい状態だと経験上考えています(なお、Flatt Securityの診断ではこういった課題を解消すべく、具体的なリスクが伝わる報告書作成に取り組んでいます)。

そのため本来のXSSの脅威が低く見られてしまっているのではないかと思い執筆に至りました。

本稿では攻撃者が実際にXSSの脆弱性をついた攻撃を行った場合にどのようなリスクが生まれるか、具体的な例を4つほどご紹介していきます。

XSS(クロスサイトスクリプティング)とは?

多くの方がXSSについて認知していると思いますが、簡単にXSSについて解説していきます。

XSSとは攻撃者が入力したJavaScriptがサニタイズ、エスケープされない状態で出力されてしまうことで、サービスを運用しているドメイン上で第三者のJavaScriptが実行されてしまう脆弱性です。被害としては「認証情報の奪取」や「悪意のあるWebサイトへのリダイレクト」「マルウェアの配布」「不正操作」など、任意のJavaScriptが実行できてしまうので、多岐にわたります。

XSSには複数の種類がありますが、本稿ではStored XSS(蓄積型)を取り扱っていきます。

Stored XSSとは入力したJavaScriptがデータベースなどに保存され、JavaScriptが出力されるページに継続的にJavaScriptが実行されるようなXSSになります。

XSSって実際にアラート以外になにができるの?

導入として、まずはアラートが発生するXSSをご紹介します。

今回の検証では弊社で作成した脆弱なTODO管理のデモアプリを使用します。

※検証用のアプリケーションになるので、XSSの攻撃に対する防御策は設定しておりません。

新規タスク登録画面の、タスク名を入力する欄がXSSに対して脆弱性になっており、以下のような <script> タグで囲まれたJavaScriptをフォームから送信するだけでアラートが発生します。

<script>alert('XSS');</script>

f:id:flattsecurity:20220218170824g:plain

上記のようにXSSを用いてアラートが表示される例はみなさんみかけたことがあるのではないでしょうか。

それでは、XSSを攻撃者が悪用した際の被害例について紹介していきます。

また、先ほど触れたように今回は蓄積型のXSSを想定しています。基本的にこれ以降に紹介するシナリオにおいては「事前に攻撃者がタスク名などにJavaScriptを含めておき、他のユーザーがそのタスクを閲覧するときにXSSが発生する」という流れで攻撃が行われます。

※キャプチャ動画の簡易化のため、本稿の検証はJavaScriptを仕掛けた攻撃者自身のアカウントでの再現になります。

認証情報の奪取

シナリオとしては、

  1. 攻撃者がCookieを奪うJavaScriptを仕込む
  2. 別のユーザーがタスク一覧を閲覧した時にCookieが攻撃者のサーバーに送信される

というものになります。

※また、今回のアプリケーションはCookieを使用する認証方式です。

f:id:flattsecurity:20220218173056g:plain

上のようにタスク一覧にアクセスするたびに、攻撃者のサーバーにCookieが送信されていることがわかります。

CookieにHttpOnly属性が付与されていない場合、このようにXSSが発生するぺージにアクセスするだけでCookieが送信されるので、アカウントを乗っ取ることができます。仮に、第三者の投稿により、管理者画面でログインCookieを取得するXSSが発生した場合に、管理者のログインCookieが奪われ被害は甚大になります。

偽ログインページ表示およびキーロガー

シナリオとしては、

  1. 攻撃者が偽のログイン画面を表示させるスクリプトとキーロガーをJavaScriptを用いて仕込む
  2. 別のユーザーがタスク一覧を閲覧した時に偽のログイン画面が表示され、ログインを試行しようとキーボード入力を行うとその内容が攻撃者のサーバーに送信される

というものになります。

f:id:flattsecurity:20220301221004g:plain

XSSによるページ改ざんを行い偽のログイン画面を表示し、その画面で入力された文字列が、リアルタイムで攻撃者のサーバーに送信されていることがわかります。

このようなXSSが発生した場合、ユーザーは入力した情報を攻撃者に奪われていることに気づかず、決済などの処理を完了してしまいます。

自動フィルイン機能経由の認証情報の奪取

シナリオとしては、

  1. 正規のログインフォーム(localhost:4567)よりログインし、タスク一覧画面に遷移する
  2. XSSが発火し、攻撃者のJavaScriptによって偽のログインフォームが表示される
  3. この時、偽のページにリダイレクトさせているのではなく、あくまで正規のタスク一覧画面の上に偽のログインフォームを被せて表示させている。その証拠にURLは localhost:4567/users/14/tasks となっている
  4. ドメインによってWebサイトが正規のものだと判別され、メールアドレスとパスワードの自動フィルインが行われる
  5. 自動フィルインで入力された内容が攻撃者のサーバーに送信される

f:id:flattsecurity:20220301232856g:plain

自動フィルインの機能を利用してブラウザやパスワード管理ツールに保存したパスワードなどを入力した場合でも、上のように、入力内容を取得することが可能です。

なお、ブラウザ/パスワード管理ツールの挙動にもよりますが、サービスのドメインとログインを行うドメインを別にしておけば、このようなケースで自動フィルイン経由で認証情報を盗まれることを防げる可能性があります。

例として、Googleアカウントのログインフォームはaccounts.google.comに切り分けられており、Microsoftアカウントはlogin.live.comでログインを行います。(両社のサービス群を考えるとセキュリティ以外の理由もありそうですが)

そもそも、サービスを運用しているドメインには以下のようなリスクがつきまといます。

  • 広告表示やトラッキングに用いるものなど運営者が導入している外部JavaScriptに悪意のあるものが混入するリスク
  • XSS脆弱性を作ってしまい、第三者のJavaScriptの攻撃を受けてしまうリスク

そこで、ログインページをサービスを運用するドメインとは別のドメインで運用し、上記のようなリスクを減らすことで、悪意のあるスクリプトがブラウザ/パスワード管理ツールから認証情報を平文で盗み出す可能性を減らすことができるのです。

XSS経由でService Workerを登録する

シナリオとしては、

  1. サービスと同一のドメインに、何らかの手段で登録させたいService WorkerのJavaScriptファイルをアップロードする
  2. XSSが発生するタスク一覧画面でService Workerを登録するJavaScriptを仕込む
  3. 別のユーザーがタスク一覧画面を閲覧した時に、ブラウザにService Workerを登録し、以降アクセスしたURLを継続的に攻撃者のサーバーに送信させる

※本稿の検証ではJavaScriptファイルは事前に配置してあります。

f:id:flattsecurity:20220301233511g:plain

上のように、XSS経由で登録させたService Workerを用いて継続的にスクリプトを実行することが可能です。これはすなわちXSS攻撃が繰り返し行われるということです。

攻撃を成立させるにはJavaScriptファイルのアップロードができ、かつXSSが発生するなどの条件はありますが、Service Workerのスコープの範囲を "/" のように指定することができれば、本来XSSが発生していないページでもJavaScriptが動作します。

また、XSSの修正をおこなったとしても、ある程度攻撃され続ける状況となります(本稿の例はXSSが発生している箇所を削除して再現)。これはここまで紹介した別のXSSにはない大きな脅威です。

終わりに

本稿ではXSS(クロスサイトスクリプティング)によって発生する被害についてご紹介しました。今回紹介したようなXSS用のJavaScriptの作成にはほとんど時間がかからず、誰でも簡単に作成することができるものになっています。

また、インターネット上には多くのXSS用のキーロガーや、偽のログイン画面を簡単に作成するようなツール、多くの悪意のあるXSS用のスクリプトが存在する状況になっています。そのため、XSSがアラートが表示されるだけの、簡単な脆弱性だとは考えずに、XSSに対しての認識が少しでも変わるように、本稿の記事がお役に立てると幸いです。

Flatt Securityでは、セキュリティエンジニアの手動検査による高品質なセキュリティ診断サービスを提供しています。レポートにおいては「どのような被害が起きるか」を具体的に想起できるよう、アラートで終わらせない脆弱性再現コードを必要に応じて提供しています。

過去に診断を実施したが不安や課題がある、予算やスケジュールに制約がありどのように診断を進めるべきか悩んでいる等、お困り事にあわせて対応策をご提案いたしますので、まずはお気軽にお問い合わせください。

お問い合わせは下記リンクよりどうぞ。

https://flatt.tech/assessment/contact

Flatt Securityはセキュリティに関する様々な発信を行っています。 最新情報を見逃さないよう、公式Twitterのフォローをぜひお願いします!

twitter.com

ここまでお読みいただきありがとうございました!