Google Apps Scriptのトークンハイジャックの記事について
Google Apps Scriptは大変便利なものなのですが、それは時としてとんでもない情報漏洩につながる可能性もあります。前回は、ウェブアプリ側からDeveloper Toolを介して、GAS側の関数を推測しWebアプリ側からアクセスできちゃう問題につづいて、Twitterに掲載されていた、OAuth Token Hijackという不穏なネタを見かけたので検証しました。
問題の内容
前提条件
Twitterに掲載されていたリンク先のページはこちら。Google VRPというセキュリティホールの通報をすることで報奨を得るバウンティ・ハンターというお仕事というか仕組みがあるのですが、そちらに報告されている内容だそうで。
その内容は結構複雑で順を追って説明が必要です。
- オーナーがGASのWebAppをデプロイ。この時権限周りは以下の通り
- アクセスできるユーザ:Googleアカウントを持つ全員
- 次のユーザとして実行:ウェブアプリケーションにアクセスしているユーザ
- 編集権限を持つ悪意のあるユーザが元のコードを変更せずに新しくgsファイルを追加してコードを追加(元のdoGetを上書きするようなウェブアプリを書く)
- 編集権限を持つ悪意のあるユーザは、組織内部のアカウントである必要があります。
- また、組織外の編集権限を持つユーザがコードを変更するとオーナーに変更した旨のメール通知が飛んできます。
但し、この時外部のユーザが組織のGoogle Workspaceアカウントではなく個人アカウントの場合には、コードを書き足すことはできても、デプロイすることはできません。
図:ウェブアプリの公開設定
図:個人のGoogleアカウントだとデプロイできない
図:この設定だと初回認証はReview Permissionの警告が出る
図:部外者の編集はオーナーに通知が飛ぶ
悪意のあるユーザによる変更
本来はオーナーの設置したdoGet関数によるウェブアプリが開かれる想定です。しかし、悪意のあるユーザは前提条件の中で、以下の作業をしています。
- オーナーのdoGet関数は一切変更しません。
- 新たにgsファイルを追加して、同じdoGet関数でウェブアプリを上書きする処理を記述する
- この時以下のことが可能になっています。
- doGetなのにウェブアプリを記述せず、別の関数を呼び出す処理を書ける
- 別の処理はアクセスしてきてるユーザアカウントのOAuth Tokenを取得してメールで外部に飛ばす処理を書いてる
- もしくはウェブアプリだけれども、UrlfetchAppを使わず、HTML側でFetch APIを叩いてトークンを外部に飛ばす処理を書いてる
- この状態で悪意のあるユーザにより上書きでデプロイされる
- デプロイ後に追加したgsファイルを削除して保存する(しかしデプロイしたアプリは継続して動いてる)
- デプロイ後の公開URLはオーナーが公開したURLと変わらない。
この時、公開されたURLにアクセスすると本来はオーナーのデプロイしたアプリが表示されるハズが、悪意のあるユーザによるおかしなウェブアプリが開かれる(オーナーのdoGetよりも下に悪意のあるgsファイルがあるので上書きされてしまう)
ユーザの被害
これは組織内外問わず、公開されてるアプリにはGoogleアカウントがあれば誰でもアクセスできてしまうので、ユーザが以下の作業をして開いてしまうと、アクセストークンが奪取されてしまう。
- Review Permissionを開いて、認証処理を許可してしまう
これだけ。すると、ウェブアプリの記述が無い場合には、実行されたけど何も表示されない結果が出てきます。しかし、後ろではユーザの権限で特定の送信先に自身のアクセストークンがメールで送信済みです。
認証処理の許可画面でメールやドライブの権限を要求されてそのまま許可してしまうと、それらのトークンが飛んでいってしまうわけです。しかもアプリをデプロイした人のではなくユーザ自身の。
図:何も表示されない結果
Googleからの回答と問題点
これに対するGoogleからの回答は以下のようなものだったそうな。
- 監査ログを監視して対応
- UrlfetchAppのアクセス先ドメインの制限
しかし、2.についてはそもそもUrlfetchAppを使わずともスルーできるだけでなく、HTML側のFetch APIを使えばこの問題は回避ができてしまうので対抗策にならない。
一方で監査ログはリアルタイム監視ができるわけでなく、表示されるまでにタイムラグがある。監査ログとUrlfetchAppのドメイン制限はエンタープライズプランでのみ利用できる機能であるため、Business Standardなどだと監視しきれない可能性が指摘されている。
また、オーナーだけがデプロイできるのであれば問題ないところを、同じ組織内のアカウントだと編集権限があれば上書きでデプロイできてしまう。
故に現時点でこの課題点に関しては、対処はされていないとのこと。
教訓
オーナー側の教訓
GASのウェブアプリのオーナーはこのような問題点があることを重々承知しなければなりません。敵は内部にあり。部外者の個人のGoogleアカウントの場合コード編集をすると通知が飛んでくるので気がつくことはできますが、内部の場合通知が来ません。
デプロイ履歴からおかしなデプロイを見つけることはできますが、常に監視してるわけでもなし。
アプリを開発する場合には、第三者に編集権限を与える場合には社内であっても、信頼できる限定されたメンバーのみとし、ましてや部外者の人の参加や個人のGoogleアカウントの参加はさせないようにしましょう。
ましてや、テナントの管理者は指定のドライブ以外で外部共有など出来るようにするべきではなく、ウェブアプリケーションのアクセスも社内のみとするなど自衛が必要になります。
ユーザ側の教訓
ユーザはなかなかこのトリックを見抜いて回避するというのは難しいかもしれません。Review Permissionが出てくるのは部外者が作ったアプリでなくとも社内で同様の公開設定をしていれば出てくる設定です。
しかも社内のアプリなのに悪意のある社内の人間によって外部にトークンが奪取されて飛ばされてるのでなかなか回避は難しい。一方で、社内展開されているわけでもない外部のGASアプリで同様のケースに出会った場合、安易にReview Permissionをクリックして要求スコープを承認するような真似はしてはいけません。
アカウントを乗っ取られることはないとはいえ、メールやドライブを一時的に第三者に利用できる状態になってしまいます。Access Tokenの寿命はおよそ1時間の設定だったハズなので、怪しいなと思ったらGoogleアカウントのサードパーティ製のアプリとサービスにて、対象アプリの接続を削除してしまいましょう。
図:接続を削除する画面