Edited at

ブラウザ拡張の権限でどこまで(悪いことを)できるのか?とその対策【デモあり】

More than 1 year has passed since last update.

[2018/07/07 追記]

本記事ではChrome拡張について説明していますが、Firefox1やEdgeの拡張機能もほぼ同じ仕組みで動いています。


Chrome拡張。便利な機能を簡単に追加できるので使っている人も多いと思います。

ただ、インストール時の権限の注意書きが分かり難いので無条件に承認(追加)していることもあるのではないかと思われます。

Chrome拡張インストール時の確認画面のキャプチャ

そこで、本記事ではChrome拡張の権限の種類・確認方法の他、拡張がどこまで(悪いことを)できるのかとその対策を3段階の権限(危険性)レベルごとに紹介していきたいと思います。


便利だが危険性もあるChrome拡張

Chrome拡張をインストールすると、Webページを読むというブラウザ本来の機能だけでなく様々なことができるようになります。

例えば、Webメールの新着通知や記事などの次ページ読み込み、ページのレイアウト変更などが有名どころかと思います。

しかし、いろいろできるということはChrome拡張が勝手にいろいろ(悪いこと)をすることも可能ということです。

ちょうど先月(2016年11月)、悪意をもったChrome拡張により被害を受けそうになったという記事 HTTP Headers という 5万人が使っている Chrome 拡張のマルウェア疑惑。セッション盗まれて BTC も盗まれそうになった話。 - clock-up-blog が投稿されました。Twitterなどでバズったので読まれた方も多いのではないかと思います。


Chrome拡張の権限

Chrome拡張の権限について以下の順番で紹介してきます。


  1. 権限の種類

  2. 確認方法

  3. (開発者向け)権限の要求方法

  4. 3段階の権限レベルごとの危険性と対策


    • 権限なし

    • 閲覧履歴の読み取り

    • 全ページのデータの読み取りと変更




権限の種類

よく使われている権限には以下のようなものがあります。


  • ページ情報(本記事ではここにフォーカスします)


    • 閲覧履歴

    • ページ上の全データ



  • クリップボード

  • 通知

  • ブックマーク

  • 画面キャプチャ

  • etc...

参考ドキュメント

Declare Permissions - Google Chrome


いつ確認される/できるか?


  • インストール/更新時に確認ダイアログがChromeによって出される

  • インストール/更新後は拡張機能ページ chrome://extensions/ から「詳細」をクリック


インストール時

image


更新時

使用権限の追加がある場合、Chromeメニューボタンが!マークになって確認できます。


  1. 権限の追加を伴うChrome拡張の追加通知

    image

  2. 通知を選択 → 権限追加の確認

    image


    • 要求される追加権限を確認できます




インストール後

拡張機能ページ chrome://extensions/ から「詳細」をクリック


  1. 拡張機能ページ chrome://extensions/

    image

  2. 「詳細」をクリックで権限・ストアリンクなどを確認可能

    image


権限の要求記述 (開発者向け)

manifest.json に keyを permissions 値を配列で書きます。

サンプルmanifest.json


manifest.json(抜粋)

    "permissions": [

"storage",
"contextMenus",
"activeTab"
],

なお、 manifest.json に書いた権限すべてがインストール時にユーザーに通知/確認されるわけではありません。

上記の例だと、storage, contextMenus, activeTab のいずれもユーザーには通知されない種類の権限ため、インストール時の確認などでは「権限無し」となります。

ユーザーに通知されない権限は Permission Warnings - Google Chrome にまとまっています。

ちなみに、 storage はCドライブなどストレージへの無制限のアクセス権限ではなく、拡張が作り出したデータ(設定値など)の保存/読み取りです(参考ドキュメント:chrome.storage - Google Chrome)。


個人情報が収集され得る権限の種類

ページ情報にアクセス可能な権限を対象に、ユーザーへの影響度のレベルをつけてみました。

(完全に独自なので、ツッコミお待ちしております。)


Level 1: 権限なし

これは一番要求される権限が少ないです。

しかし、権限無しでも特定の条件下でできることがあります。


確認方法


  • インストール時の確認ダイアログ

    インストール時の確認ダイアログ

  • 拡張機能ページ chrome://extensions/ から「詳細」を確認した時の情報

    拡張機能ページ chrome://extensions/ から「詳細」を確認


何ができるか



  • ユーザーが特定の操作をした時にのみページ情報取得


    • 右クリックメニューから拡張のメニュー選択

    • URLバー右の拡張アイコンクリック

    • 拡張に設定されているキーボードショートカット押下



  • 取得可能なページ情報


    • ページタイトル

    • ページURL

    • ページソース全て


      • 読み取り


        • ログインフォームの入力文字


          • パスワード含む

          • Chromeによる自動入力の場合含む



        • (例:オンラインバンキング)口座番号・残高

        • など



      • 変更


        • リンク先の変更

        • (例:ECサイト)注文数の変更

        • など



      • 操作


        • 文字入力

        • クリック

        • 新規リクエスト( fetch, XMLHttpRequest )作成

        • など





    • Cookie (非httpOnly)




デモChrome拡張


  • ソースコード→ GitHub: tksugimoto/chrome-extension_test-extension-permission

  • Chrome ウェブストア → Chrome拡張の権限テスト - Chrome ウェブストア

  • 拡張の機能


    • 右クリックメニューのメニュー選択などをした時に、閲覧中のページ内の入力欄の情報を集めて別タブに表示


      • 右クリックメニューから拡張のメニュー選択


        • メニュー「入力欄のテキストを収集するテスト」



      • URLバー右の拡張アイコンクリック

      • 拡張に設定されているキーボードショートカット押下





    • ページタイトル・ページURLも表示




    1. 適当なページで右クリック→「入力欄のテキストを収集するテスト」を選択

      image

    2. 新しいタブで入力欄の情報が一覧表示

      image


      • ※ パスワードは3文字目以降を * にするようにしています。ブラウザのConsoleを開いてページ更新で全ての入力値がコンソールに表示されます。

      • ※ 表示されているパスワード( zx****... )はデモ用に適当に入力しました(念のため)。






対策


  • ログインフォームなど重要な情報が含まれているページでは拡張に関連する操作をしない


    • 右クリックメニューから拡張のメニュー選択

    • URLバー右の拡張アイコンクリック

    • 拡張に設定されているキーボードショートカット押下



  • 気にしない


    • 攻撃者の立場からすると、ユーザーが何か操作したときにしか情報を収集できないのは非効率すぎるので、わざわざ「権限無し」で悪意ある拡張を配布することは少ないのではないかと思います

    • まずは、このタイプの拡張よりも Level 2以降の注意すべき権限を要求している拡張に気をつけるべきです




Level 2: 閲覧履歴の読み取り

閲覧履歴の取得が可能です。

また、Level 1(権限なし)でできることも同様にできます。


確認方法


  • インストール時の確認ダイアログ

    image

  • 拡張機能ページ chrome://extensions/ から「詳細」を確認した時の情報

    image


何ができるか


  • ユーザーがどんなページを見ているか取得可能


    • ページURL

    • ページタイトル

    • ページfavicon

    • 閲覧開始時刻~終了時刻

    • タブ / ウィンドウの切り替え




デモ拡張


  • ソースコード→ 公開しません(悪用防止の為)

  • Chrome ウェブストア → 公開しません

  • 拡張の機能


    • ユーザーがいつ、どのページを見た/閉じたかを記録します

    • ユーザーの(インストール以外の)操作は必要ありません

    • インストールしてしまったら自動で全ての閲覧ログを記録します





  • image


対策


ユーザー向け


  • 本当に「閲覧権限の読み取り」が必要か検討


    • 不要な場合(怪しいことをしているか、「とりあえず tabs 権限を追加」している可能性があります)


      • 類似の拡張機能でより権限の少ないものがないか検索

      • 自作!



    • 必要な場合


      • レビューを確認(しないよりはまし程度)


        • 権限についての指摘がないかどうか

        • ※ 指摘がない場合でも安全であることを保証しているとは限りません

        • ※ ユーザー数が多いことも安全であることを保証しません



      • ソースコードが公開されていれば確認


        • 悪意ある攻撃者がわざわざソースコードを公開することは少ないのではないかと思います


          • ※ 公開したソースコードに手を加えたものをChrome ウェブストアで公開することも可能です



        • 確実なのは、ソースコードの安全を確認 → そのソースコード(ローカル)からChromeに拡張インストールすることです


          • 拡張の更新時に悪意あるコードが追加されるとされるということも回避できます










開発者向け(疑われないために)



  • tabs 権限の削除または activeTab 権限への変更を検討してみてください



    • chrome.tabs APIのすべてのメソッドは tabs 権限なしでも使えます


      • タブを開く, タブ関連のイベントリスナー登録など

      • ※ ユーザーの操作なしに url, title, favIconUrl にアクセスしたいときだけ tabs 権限が必要です





    • ページの url, title, favIconUrl を取得したい場合も、ユーザーの操作(右クリックメニュー、アイコンクリックなど)のときで良いなら activeTab 権限で十分です

    • 参考






Level 3: 全ページ( or 特定ページ)のデータの読み取りと変更

やりたい放題できます。

全ページ対象の場合は、Level 2(閲覧履歴の読み取り)でできることも同様にできます。

特定ページ対象の場合は、そのページの閲覧状況のみ取得可能です。


確認方法



  • インストール時の確認ダイアログ


    • 全ページ対象の場合

      image

    • 特定ページ(GitHub)のみ対象の場合

      image




  • 拡張機能ページ chrome://extensions/ から「詳細」を確認した時の情報


    • 全ページ対象の場合

      image

    • 特定ページ(GitHub)のみ対象の場合

      image




何ができるか


  • Level 1(権限なし)のユーザー操作時にできたことを、ユーザーの操作なしで実行


    • ページタイトルの取得/変更

    • ページURLの取得/変更

    • ページソース全て


      • 読み取り


        • ログインフォームの入力文字


          • パスワード含む

          • Chromeによる自動入力の場合含む



        • (例:オンラインバンキング)口座番号・残高

        • など



      • 変更


        • リンク先の変更

        • (例:ECサイト)注文数の変更

        • など



      • 操作


        • 文字入力

        • クリック

        • 新規リクエスト( fetch, XMLHttpRequest )作成

        • など





    • Cookie



つまり、ページを勝手に開いて、Chromeのパスワード入力機能によるパスワードが入力されたらその値を外部へ送り、そのページ(タブ)は閉じておくということもできてしまうのです。

他にも、SNSや掲示板を開いて適当な文章を勝手に投稿することも可能です。


対策


ユーザー向け


  • 本当に全ページのデータへのアクセス権が必要か検討


    • 不要な場合(怪しいことをしているか、「とりあえず全ページへのアクセス権限を追加」している可能性があります)


      • 類似の拡張機能でより権限の少ないものがないか検索

      • 自作!



    • 必要な場合


      • レビューを確認(しないよりはまし程度)


        • 権限についての指摘がないかどうか

        • ※ 指摘がない場合でも安全であることを保証しているとは限りません

        • ※ ユーザー数が多いことも安全であることを保証しません



      • ソースコードが公開されていれば確認


        • 悪意ある攻撃者がわざわざソースコードを公開することは少ないのではないかと思います


          • ※ 公開したソースコードに手を加えたものをChrome ウェブストアで公開することも可能です



        • 確実なのは、ソースコードの安全を確認 → そのソースコード(ローカル)からChromeに拡張インストールすることです


          • 拡張の更新時に悪意あるコードが追加されるとされるということも回避できます










開発者向け(疑われないために)


  • 全ページへのアクセスする権限の削除または 一部のページへのアクセスする権限への変更を検討してみてください

    とりあえず <all_urls> と書いている拡張があったりしないでしょうか?




おわりに

Chrome拡張は便利な反面、やろうと思えばなんでもできてしまうということが分かっていただけたでしょうか?

この記事をきっかけに少しでもChrome拡張の「権限」を意識する人が増えたらうれしいです。


この記事は Tech-Circle Hands on Advent Calendar 2016 - Qiita の3日目の記事でした。

昨日(2日目)は Sheile さんの 2年ぐらいJavaScriptから離れていた人に贈るES6対応表 でした。

明日(4日目)は bbrfkr さんの ansibleのロールを直接実行できる、ansible-artというツールを作った。 です。