ブラウザでSymbolブロックチェーンを体験・活用できるChrome拡張機能「SSS-Extension」の安全性をちょっと見てみた

# ご挨拶
以前、ちょっとした深夜テンションで[待望のSymbolのChrome拡張機能「SSS Extension」を使ってみた](https://qiita.com/gnapha/items/1ba3ed0eb89f3a079098)という記事を書いてみました。
多くの方に読んでいただけて恐縮の限りです。
情報処理試験やAWSの資格取得に時間を割いてしまっており、続きが遅くなりました、、、

# はじめに
自分の記事でも、他のSSS Extensionを使用されている方のコメント等を読んでも、**SSS Extensionが安全なら大丈夫**と表現していました。
下に記載しているきっかけから、実際に大丈夫かどうか見たんだっけ、、、誰か見てるんだっけ、、、とふと思いまして、SSS Extensionについて安全性を確認してみたく思いました。

[こちら](https://zenn.dev/inatatsu/articles/51c1d8de76d335)で、開発者のいなたつさん自身がSSS-Extensionの技術的な実装についてコメントしてくださっています。勉強になりました。

# 内容サマリ
- 信じられる仕組みを開発者が導入してくれています
- Chromeに対する未知のゼロデイ攻撃が行われたり、ウイルスや物理的にPCそのもののストレージにアクセスされる場合、安全ではありません（パスワードが**絶対に**流出していないならまあ大丈夫だとは思いますが、、）
- SSS Extensionはお金を移動させるだけ用のウォレットとして運用すれば安心です（開発者も推奨しています）
- 不安があれば、せっかくOSSで公開してくれていますし自分でインストールも有効だと思います（方法は下記に記載しました）

# 気になったきっかけ
以下のような画像が拡張機能導入時に表示され、ちょっと気になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/758b6a91-e60a-f6ac-cb92-2b8867421a92.png)

[ブラウザ拡張の権限でどこまで（悪いことを）できるのか？とその対策【デモあり】](https://qiita.com/tksugimoto/items/0e9ada7efc3b6570e10c)という記事では、かなり分かり易くChrome拡張機能について記載されております。
その中に、上記のような**すべてのウェブサイト上にある自分の全データの読み取りと変更**と案内が出る拡張機能が出来ることとして、以下のような記述があり
```
Level 3: 全ページ（ or 特定ページ）のデータの読み取りと変更
やりたい放題できます。

全ページ対象の場合は、Level 2（閲覧履歴の読み取り）でできることも同様にできます。
特定ページ対象の場合は、そのページの閲覧状況のみ取得可能です。

～～中略～～

何ができるか
Level 1（権限なし）のユーザー操作時にできたことを、ユーザーの操作なしで実行
- ページタイトルの取得/変更
- ページURLの取得/変更
- ページソース全て
  - 読み取り
    - ログインフォームの入力文字
      - パスワード含む
      - Chromeによる自動入力の場合含む
    - （例：オンラインバンキング）口座番号・残高
    - など
  - 変更
    - リンク先の変更
    - （例：ECサイト）注文数の変更
    - など
  - 操作
    - 文字入力
    - クリック
    - 新規リクエスト（ fetch, XMLHttpRequest ）作成
    - など
- Cookie
つまり、ページを勝手に開いて、Chromeのパスワード入力機能によるパスワードが入力されたらその値を外部へ送り、そのページ（タブ）は閉じておくということもできてしまうのです。
他にも、SNSや掲示板を開いて適当な文章を勝手に投稿することも可能です。
```

実際にChrome拡張機能ってどうなってるか見てみるべきか、、と思った次第です。

# 拡張機能を使用するうえで、発生したら恐ろしいこと
拡張機能を使う上で気にすべきセキュリティ上の懸念とは何があるかを考えてみました。
- ブラウザ上の入力情報などを収集される（悪用も怖いですし単になんだか嫌ですよね、、）
    - 見ているページの情報
    - 履歴の情報
    - どこかのサービスに入る際にID・パスワードなど
- 拡張機能に入力した情報が想定外の使い方をされる
    - 今回の例でいうと秘密鍵が漏洩し、拡張機能が勝手にトランザクションに署名する（勝手にXYMを使われる）など

# 一般的な拡張機能で言えること

### 1. 拡張機能の中身は基本的にはGoogleの審査を信頼するほかない
最近の審査では比較的しっかり見てくれるそうですが、昔の審査はかなり甘かったそうです。いまでもたまに拡張機能の不正がリリース後に判明してストアから削除されています。
開発者がソースコードを公開してくれているものも数多くありますが、**厳密に拡張機能のソースが公開されているものと同一であるか判断するには骨が折れます**。
というのも、ハッシュIDのようなものでストアが公開ソースと同一であることを示す機能などは存在しないため、インストールされたローカルにある拡張機能と比較する必要があります。バンドル後のソースを比較・機能に問題が無いかをアップデートがあるごとに確認するのは大変そうです、、
（ローカルにインストールされた拡張機能のソースコードには`_metadata/verified_contents.json`といったハッシュファイルがあるので、Chrome側からはハッシュ等でローカルに入れた拡張機能のソースコードの変更・改ざんは見れていそうでしたが、このファイルについての詳細を発見できず、、）

### 2. 拡張機能のストレージ機能は標準では暗号化されておらず、機密データの保存は**非推奨**
[Chrome拡張機能におけるストレージ機能のドキュメント](https://developer.chrome.com/docs/extensions/reference/storage/)では、
```
Warning
Confidential user information should not be stored! The storage area isn't encrypted.
```
と記載があります。（訳：ストレージ領域は暗号化されていないので、機密のユーザ情報は保存しないでください）

### 3. 高特権アクセス権を持つ拡張機能や、許可を得た別プロセスからもストレージ機能に保存されたデータにはアクセス可能（らしい、、）
すみません、ここはあまり勘所が無いのですが、[このようなやり取り](https://code-examples.net/ja/q/1b38bd6)があり、アクセスは出来てしまうとの回答がされていました。



# 今回のSSS-Extensionの対策

### 対策ポイント1: 潔白性の証明として、ソースコードをオープン化してくれている
この対策によって、一般的な拡張機能で言えることで一点目に挙げていた`1. 拡張機能の中身は基本的にはGoogleの審査を信頼するほかない`に対して手が打たれていると思います。
以下、そのオープンなソースに対してどう向き合うか記載しました。

- 対応その１：オープンなソースを信じる
まず、[SSS-Extension](https://github.com/inatatsu-tatsuhiro/SSS-Extension)のソースコードがGitHubにて公開されています。
このソースコードを読んで、外部に通信して情報を送っていないかや、秘密鍵がきちんと守られているか確認することができます。（秘密鍵についてはこのあとソースコード解説も勝手にさせていただきました。）
ただ、そのソースコードから作られた拡張機能が本当に自分のChromeに入っているのか？は確認が必要です。

- 対応その２：ソースコードを調べる
Googleの審査や開発者を信じるなら対応その1だけでいいのですが、もう少し自分で見たいという場合、ソースコードを比較しましょう。
Chrome拡張機能はインストール後、ローカルに保存されます。
自分の環境では`C:\Users\<ユーザ名>\AppData\Local\Google\Chrome\User Data\Profile 1\Extensions\llildiojemakefgnhhkmiiffonembcan\1.1.1_0`にありました。
Extensions以下の文字列は、下記画像のように拡張機能一覧ページで設定されているIDになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/a3dc4548-c1ca-d58d-af11-16217fce3ab9.png)

このフォルダ内のソースコードと、GitHubなどで公開されているソースコードを比較し、一致していればいったんは安心です。
しかし、ここまで気にするのであれば、アップデートがある度に確認を続けるべきかな～と思います。大変です。

- 対応その３：自分でビルドする
上述した通り、ソースコードが仮にオープンであったとしても、**本当にそのソースがいまインストールされているアプリなのか**調べるのは骨が折れます。
そこで、せっかくオープンにソースコードを公開してくれているし、自分でソースコードをビルドしてローカルインストールしてしまおうという対策が可能です。
個人的には、ビルド後のファイルやビルド手順が明示されたドキュメントもGutHubにあがっているとより理想的だと思いました。
ただ、この方法でもソースコードに不正が無いかのチェックは自分でしましょう、、オープンなソースコードだからといってそこに不正が無い証拠であるわけではないので、、

~~手順をここに書くと見通しが悪いので、おまけとして最後に書いています。~~
すみません自分の知識が不足しており、ビルドしたソースコードを自分で登録するとエラーが出てしまい、この方法は取れませんでした、、

### 対策ポイント2: パスフレーズを用いて、拡張機能によって秘密鍵情報を暗号化している
ソースコードがオープンだからいい！では流石に短絡的なので、少しソースコードを見つつ重要そうな箇所をピックアップしてみました。（かなり筆者の気になりポイントに偏っていると思います）
この対策によって、一般的な拡張機能で言えることで一点目に挙げていた`2. 拡張機能のストレージ機能は標準では暗号化されておらず、機密データの保存は非推奨`と`3. 高特権アクセス権を持つ拡張機能や、許可を得た別プロセスからもストレージ機能に保存されたデータにはアクセス可能（らしい、、）`に対して手が打たれていると思います。（秘密鍵を保存しているが、安全な方法をアプリレイヤで担保しているため、アクセスされることがあっても一応安全）

- 秘密鍵は暗号化されており、平文（非暗号化状態）で保存はされていない
拡張機能（等）の保存領域を見ることが出来る拡張機能`Storage Area Explorer`を使ってSSS-Extensionの保存領域に入っている情報を確認します。
activeAccountキー内の情報は以下のようになっており、暗号化された秘密鍵が格納されています。
```json
{
	"address": "TCVXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
	"encriptedPrivateKey": "U2FsdGVkX19ws~~中略~~WKltnp+lMnv4e41kvv7Y62q1wA=",
	"name": "dev",
	"publicKey": "98EA765D7XXXXXXXXXXXXXXXX公開鍵XXXXXXXXXXXXXXXXXXXX192BC19470E3",
	"seed": 615,
	"type": "PASS"
}
```

- 秘密鍵はユーザのパスワードで暗号化されており、そのパスワードはユーザしか知らない（ので実質本人しか秘密鍵を取り出せない）
「正しいパスワードを保存領域に持ってたらそれを見れば秘密鍵が分かっちゃうじゃん！」と最初思いましたが、とてもいい方法で対策がされていました。クレバーです。
ソースコードでいうと[この位置](https://github.com/inatatsu-tatsuhiro/SSS-Extension/blob/20da51a2aaba543f18345af44ab084fc1636ec2b/src/_general/lib/validator/index.ts#L35)だと思っています。
ログイン時に入力されたパスワードで暗号化された秘密鍵を複合し、その秘密鍵から公開鍵を作成し、登録された公開鍵と作成された公開鍵が正しければログイン成功というロジックのようです。
この方法なら、確かに拡張機能上のどこにもパスワードを保存することなく（ユーザが覚えている必要は勿論あります）、秘密鍵の暗号化と保存が可能ですね！！
これは本当に感心しました。認証サーバに依存しないログイン方法で鮮やかです。

### 対策ポイント3: 拡張機能を使える範囲を限定している
- 右クリックから許可するドメインを追加し、追加されたドメインで拡張機能が動作するように実装している
以下画像のように、右クリックメニューからSSS連携を明示的に許可しないとトランザクションへの署名依頼などの機能が使用できなくなっています。意図しないサイトが勝手にトランザクション依頼をしていて、よくわからないトランザクションに署名をしてしまうリスクが軽減されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/8e9b21f9-8256-3e35-08c9-d0bd7a1ec633.png)
Chrome拡張機能の設定として、許可したドメインでのみ動作させる設定がありそうなので、それで代替できればより良さそうな印象は持ちました。（これはそもそも難しい話であればすみません、、勉強不足です、、）
この拡張機能自体の設定のレイヤをイメージしています。
拡張機能の機能のレイヤではなく、拡張機能自体を管理するChromeレイヤで制御できればな、という意味です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/477334ad-cb8f-3a3f-8d9f-159eec2162aa.png)


# おまけ：拡張機能を自分でビルドしインストール
- 筆者はwin環境にwslでUbuntu20.04を入れています
- せっかく素晴らしい拡張機能を作ってくださったので、個人的には拡張機能ストアのページのDL数やスター数を稼いでみんなに使われる拡張機能だと示したいのでこの方法は参考までに、、
- と思ったらそもそもできませんでした、、できた段階まで書いています。

### 1. SSS-Extensionをcloneし、環境を整える
```
git clone https://github.com/inatatsu-tatsuhiro/SSS-Extension.git
cd SSS-Extension
npm i
```

### 2. ビルドする
```
yarn run build
```

### 3. 拡張機能に登録する
- Chromeの[拡張機能一覧画面](chrome://extensions/)からデベロッパーモードをオンにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/5c4164e8-23ca-f1fc-2f83-dc98bdf5991a.png)

- `パッケージ化されていない拡張機能を読み込む`から、先ほどビルドした結果のファイル`buildフォルダ`を読み込む

---

**ここまでやって拡張機能をロードしましたが、スクリプトのインジェクト?の設定が悪いのか、うまいこと導入できませんでした、、すみません、、**
以下エラー例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/a6c76798-d218-d32c-3c12-a807dad491b3.png)

### 4. 自分でビルドはとりあえずできませんでした、、出来た方ぜひ情報提供いただけると、、
- やります！って言っておいてすみませんでした、、現状はストアから導入+ソース調査+開発者の信頼が必要です

# 要望・期待のまとめ
もしできるなら、上述した許可ドメインの話にも似ていますが、（すみませんしっかり分かっておらず）拡張機能としてのアクセス権限をActiveTabのレベルにしてもらえると安心感が増すな～と思いました。
拡張機能側の設定として、右クリックで許可したサイトのみで使える仕様となっていますが、**できるかできないかで言えば**、開発者側のソース次第で全てのリソースにアクセスできてしまうように感じています。（もちろん、**開発者を疑う気はありません**が、セキュリティの考え方的にこういうのは大切だと思っています）
そもそもストアに出している権限（Manifest）レベルで絞られていれば、そのような懸念も無くて嬉しく思いました。
自分が分かっておらず、機能実現の問題上それが必須であった場合すみません、、DMやコメントいただければすぐ謝罪しつつ修正します。

- 拡張機能が動かせる範囲：全タブ全ページ→現在アクティブなタブのみ
- 拡張機能の関数などを呼べる範囲：右クリックで許可したドメイン→拡張機能制御レイヤで許可したドメイン
のイメージです！

また、公開されているソースコードには、明確なビルド手順やビルド後のフォルダ（拡張機能としてインストールされる静的なバンドル後のファイル）なども含まれていると比較し易くて理想的です。

# ~~疑問~~ (0220510追記：爆速で開発者さんが対応してくださいました！感謝！)
~~現在公開してくれているソースコードは1.1.0が最新でしょうか？
5月8日22時段階ですと、GitHubのタグでは1.1.0が最新となっていますが、拡張機能ストアで公開されているのは1.1.1となっているような、、~~
~~↓GitHubの最新~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/011ec817-4129-2405-b7b8-ee81e4b08f0f.png)

~~↓拡張機能画面~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/0f95c6e8-49ab-f0cb-7b0e-7aad7115f3c1.png)

~~↓インストールされたローカルのmanifest.jsonの中身~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277262/4fa47715-bcca-071f-7f1f-b69aaebbe8f9.png)

~~pushし忘れだったりすると、お金に関わる拡張機能なのでちょっと怖いな～というのが正直なところでした！~~
~~（かなりオープンにしてくれており、信頼出来そうな凄腕開発者であるとリスペクトしております！攻撃の意図は全くございません！いつもありがとうございます！！）~~


---
以上となります。長文となりましたがお付き合いいただきありがとうございました。
開発者も言及していますが、最低限使うお金を入れて、この拡張機能は移動用財布として使うことでより安心でき、望ましい使い方だと思います！（Not 貯金箱）

この記事が投石になってしまわないように気を付けたつもりです。
表現が悪いなどあれば、ぜひどなたでもご指摘ください。
Qiitaコメントだと気付かないこともあるので、Twitterに頂けると特にありがたいです。