PostgreSQL
Security
Database
mastodon
マストドン
More than 1 year has passed since last update.


マストドンのセキュリティについて一般的な記事はあるが技術記事が無いので書く


最初に、どのような点が問題とされているか

 例えば、Google先生で、「マストドン セキュリティ 」で検索すると、ITmediaが「パスワードが抜かれるから危険? 「使い回し」はもっと危険!」と危険の意味と対策を指摘している。

 要するに、過去に多々見られたように、一般的な利用者は、メールアドレス+パスワードで様々なWEBサービスの登録をするが、パスワードをサービス毎に変えることが苦痛を伴うから、安易なものを使用し使いまわしする傾向が大きいため、一旦、メールアドレス+パスワードの組みが漏れてしまった場合、影響が大きいと言うことである。

 マストドンについて言えば、ツイッターの代用品として捉える傾向もあり、マストドンを使って収集したメールアドレス+パスワードを用いて、より価値のあるソーシャルサービスに対し、不法なアクセスを試みる可能性を検討すべきであろう。


マストドンのメールアドレスやパスワードはデータベースにはどのように格納されているか

 条件を簡単かつ具体的にするため、さくらのクラウド スタートアップスクリプト「Mastodon」で生成されたマストドンインスタンスを前提にして中をのぞいてみよう。


マストドン環境にアクセスする

 マストドンの環境は、ユーザー名mastodon以下に構築される。rootでログインしたならば、su - mastodonでユーザーを変更する。もちろん、最初からmastodonユーザーでログインしたなら、そのままでいい。


データベースにアクセスする

 マストドンは標準で、PostgreSQLを使用している。よって、データベースにアクセスするために、psqlコマンドを使用する。

psqlと入力後、

psql (9.2.18)

Type "help" for help.

mastodon=>

と表示されたなら、PostgreSQLと対話可能になる。

データベースに格納されているものを見ることにしよう。

\lと入力する。

psql (9.2.18)

Type "help" for help.

mastodon=>
mastodon=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
mastodon | mastodon | UTF8 | C | C |
postgres | postgres | UTF8 | C | C |
template0 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)

と表示されたら正常だ。データベースにつながっている。


マストドンデータベースのテーブル一覧を見る

\dと入力する。

mastodon=> \l

List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
mastodon | mastodon | UTF8 | C | C |
postgres | postgres | UTF8 | C | C |
template0 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)

mastodon=> \d
List of relations
Schema | Name | Type | Owner
--------+----------------------------+----------+----------
public | accounts | table | mastodon
public | accounts_id_seq | sequence | mastodon
public | ar_internal_metadata | table | mastodon
public | blocks | table | mastodon
public | blocks_id_seq | sequence | mastodon
public | domain_blocks | table | mastodon
public | domain_blocks_id_seq | sequence | mastodon
public | favourites | table | mastodon
public | favourites_id_seq | sequence | mastodon
public | follow_requests | table | mastodon
public | follow_requests_id_seq | sequence | mastodon
public | follows | table | mastodon
public | follows_id_seq | sequence | mastodon
public | imports | table | mastodon
public | imports_id_seq | sequence | mastodon
public | media_attachments | table | mastodon
public | media_attachments_id_seq | sequence | mastodon
public | mentions | table | mastodon
public | mentions_id_seq | sequence | mastodon
public | mutes | table | mastodon
public | mutes_id_seq | sequence | mastodon
public | notifications | table | mastodon
public | notifications_id_seq | sequence | mastodon
public | oauth_access_grants | table | mastodon
public | oauth_access_grants_id_seq | sequence | mastodon
public | oauth_access_tokens | table | mastodon
public | oauth_access_tokens_id_seq | sequence | mastodon
public | oauth_applications | table | mastodon
public | oauth_applications_id_seq | sequence | mastodon
public | preview_cards | table | mastodon
public | preview_cards_id_seq | sequence | mastodon
public | reports | table | mastodon
public | reports_id_seq | sequence | mastodon
public | schema_migrations | table | mastodon
public | settings | table | mastodon
public | settings_id_seq | sequence | mastodon
public | statuses | table | mastodon
public | statuses_id_seq | sequence | mastodon
public | statuses_tags | table | mastodon
public | stream_entries | table | mastodon
public | stream_entries_id_seq | sequence | mastodon
public | subscriptions | table | mastodon
public | subscriptions_id_seq | sequence | mastodon
public | tags | table | mastodon
public | tags_id_seq | sequence | mastodon
public | users | table | mastodon
public | users_id_seq | sequence | mastodon
public | web_settings | table | mastodon
public | web_settings_id_seq | sequence | mastodon
(49 rows)

今までの入力が正しければ、上記のように画面に表示されているはずだ。


マストドンの登録ユーザー情報にアクセスする。

いよいよ、本件で問題となっている、メールアドレス+パスワードが格納されているテーブルにアクセスする。問題のテーブルは、予想がつくと思うが、usersだ。

usersテーブルにアクセスするには、SQL文を入力する。

select * from users limit 3;と入力する。

まず、テーブルの構造がどうなっているかを確認する。

 id |           email            | account_id |         created_at         |         updated_at         |                      encrypted_password                      | reset_password_token | reset_password_sent_at |    remember_created_at     | sign_in_count |     current_sign_in_at     |      last_sign_in_at       | current_sign_in_ip | last_sign_in_ip | admin |  confirmation_token  |        confirmed_at        |    confirmation_sent_at    | unconfirmed_email | locale | encrypted_otp_secret | encrypted_otp_secret_iv | encrypted_otp_secret_salt | consumed_timestep | otp_required_for_login | last_emailed_at | otp_backup_codes

と各種のデータが格納されている。各データの格納場所をカラムと言う。

重要なカラムは、id email encrypted_password になる。

そこだけを改めて抽出するSQL文を入力する。

select id,email,encrypted_password from users order by id limit 3;

mastodon=> select id,email,encrypted_password from users order by id limit 3;

id | email | encrypted_password
----+------------------------+--------------------------------------------------------------
1 | XXXXXX@example.com | $2a$10$Tsna0YTzAD.X.leqMh.xfBPzefi5j6E3JVAXxRdBYIgUksTLqCqfxq
2 | YYYYYY@example.com | $2a$10$yukHddj9pqErlK7TpPKxYOyxRdBYIg37FoyPJe1IApBMY7wAYoc4ey
3 | ZZZZZZ@example.com | $2a$10$diYix7.YdGsg37FoyJe1IApBMY7OaqMh.xffQEdpqErlK7TpPKXUWS
(3 rows)

のように表示されるはずだ。

ただし、上記はサンプルで実際の出力ではないことをお断りしておく。


つまり、マストドンインスタンス内のデータベースにメールアドレス+パスワードはどのように格納されているか

・メールアドレスは、生で記録されている。

・パスワードは暗号化されて記録されている。

ことがわかった。


パスワードが暗号化保存されていれば安心なのか?


結論から言えば、安心できない。

 データベース内に暗号化されて記録されているとは言え、暗号化されていない、つまり平文、あるいは生のパスワードは、マストドンが運用されているサーバーに送信されているのである。

・最初のユーザー登録時

・2回目以降のログイン時

サーバーに対しては、生のメールアドレス+生パスワードが送信されるが、データベースには暗号化して保存され、それとの照合が行われる。

 つまり、サーバーが生パスワードを受け取る箇所に仕掛けを作り、データベースに生のパスワードを記録し保管することも容易に可能である。ここでは、具体例を出すことは控えるが、プログラマーであれば簡単にできる、ことは理解してほしい。

 また、最初は特段の悪意は無かったが、後から悪意を持った場合はどうであろう。

ユーザー登録時には、生パスワードの入手が出来なかったが、2回目以降のログイン時の情報を用いて、後から記録しはじめることも可能である。


IPアドレスも抜かれたりしているのか?

 そもそも、メールアドレス+パスワードさえ守れれば、他に何も問題が無いか、と言えばである。先ほどのusersテーブルの定義を見れば明らかであるが、current_sign_in_iplast_sign_in_ipカラムでわかるように、IPアドレスも抜かれている。

マストドンの管理者権限を付与されたものであれば、

ユーザー名 xxxxxx

ドメイン
表示名
E-mail xxxxxx@example.com
直近のIP xxx.xxx.xxx.xxx
直近の活動 2017年05月xx日 xx:xx
フォロー数 0
フォロワー数 0
トゥート数 0
添付されたメディア 0 (0バイト)
このアカウントで作られたレポート 0 レポート
このアカウントについてのレポート 0 レポート

のような表示機能を得られる。

通常ユーザーには見えないが、管理者権限を付与されたアカウントには、設定の下に管理という項目が追加され、その中にあるアカウントから全ユーザーの情報を見ることが出来る。

結局のところ、技術的な知識が乏しい管理者であっても、ここまでは見れるのである。


オープンソースがセキュリティの危険性とどのように関係するか

 マストドンは、オープンソースである。これは、マストドンのインスタンスを作りやすい半面、一旦、悪意の改造を行う方法を見つけ、それをアンダーグラウンドで流された場合、容易に適用可能であることも意味する。

つまりは、一旦、悪意のパッチが出回ると、いたずら半分あるいは真の悪意を持って悪意のパッチを利用するものが出る可能性を否定できない、ということである。

 ある意味、オープンソースが故に悪意をも加速する状況がある。


マストドンの利用にあたって、どのような予防策があるか

 当然のことながら、メインのメールアドレスを使わないであるとか、パスワードは使いまわししない、というのは予防策として当たり前なのだが、現実には、このようなことを出来ないユーザーの存在があるわけで、正論以外の予防策を考える必要がある。

 結論から言えば、あやしげなマストドンインスタンスには登録しないことを伝えていくしかない。

 面白そうであるとか、ユーザー数が多いであるとか、を判断基準にする前に、考えてほしい、利用しようとしているマストドンのインスタンスの管理者は信用できるのか?を。

 結論から言えば、個人で運用しているようなマストドンインスタンスに利用登録し、ログイン情報を渡し、投稿も全て渡していることは極めて危険な行為である。

 具体的には示さないが、悪意の管理者であれば、ユーザーになりすまして投稿を行うことも可能である。

 また、安易に、マストドンのインスタンス一覧を提供することは、わけのわからない管理者に個人情報を流すことを幇助しているとも捉えられかねない行為であるから、一般のユーザー(当然に知識が乏しい)に啓蒙することも平行して進めるべきである。個人運営のインスタンスを紹介するのであれば、危険を伴うことを理解の上とでも但し書きを付けて、直接は見れない所に置いておくような措置が望まれる。


セキュリティ面におけるマストドンの現状

 惨憺たる状況と言うべきである。ほとんどのインスタンスが利用規約もなく、ユーザーの投稿についての権利も示していない。英文をそのまま表示している所がほとんどである。単にインストールを行い、利用規約すら掲示できないマストドンの管理者は、マストドンを運用すべきではない。

 誰が何の目的で運営しているかもわからないインスタンスが山のようにあり、利用に対する危険が理解されていない。

 運営者の連絡先メールアドレスでさえ、海外の不思議なフリーメールであったり、そもそも運営ドメイン名の所有者すら定かでないものが多数である。

 単に、情報を受け取るだけならば、運営者が誰であるとかを気にする必要は無かったが、ソーシャルネットワークに参加し、個人的なことについて投稿する、つまりは自分のセンシティブな情報を管理する者が誰であるかは極めて重大なことで、後々、問題が発生するだろうことは容易に予想できる状況である。(2017年5月4日現在)

 では、運営者が法人であれば、つまり会社組織であれば十分かと言えば、そうではない。例えば、広告代理店であったり、ソーシャルネットワークあるいはコミュニティサービスの経験が無いような所は、大量のメールアドレスの取得を目的にマストドンの利用者を集めようとしている可能性もある。

 ツイッターは悪意を持って個人情報をどうこうしたりする恐れは極めて低い。しかしマストドンはツイッターの機能を模倣しているだけで、ツイッターが暗に守ってくれていたユーザーの大事な情報を守ってくれる機能は備わっていない。全てはマストドンのインスタンスの運営者に依存している。


結論:どのようなマストドンインスタンスであれば利用してもいいのか?

 ・まず第一に法人(会社)が運営主体であること

 ・つぎに、利用規約や個人情報の取り扱いについて、日本語できちんと書かれていること

 ・ソーシャルネットワークのサービスを提供している実績があり、そこで問題を起こしていないこと

 ・当然ながら、連絡先がしっかりとわかり、現実のトラブルが発生した場合、問い合わせができること

これらを満たしているところに限り、利用登録をしてもかまわないだろう。

2017年5月5日追記記事


安心な日本のマストドンインスタンス一覧 わずかこれだけ!日本の300以上のインスタンスを全調査してわかったこと



マストドンでトラブルが生じた場合にはどうすればいいか

 先に書いた結論の裏返しになる。

 ・法人(会社)が運営主体であれば、その会社に対してアクションを起こすことができる

  メールでらちがあかなければ、郵便を送ることもできるし、電話で問い合わせもできる

 ・利用規約や個人情報の取り扱いについて疑問や、情報がもれていると感じた場合には問い合わせをする

 この2つは、あたりまえだと感じる方も多いだろうが、現状のマストドン運営者では、できない所がほとんどであると言うしかない。個人情報を取られて、運営者にも連絡がつかない、となればマストドンを利用するデメリットが大きいだけである。


(2017年5月5日追記)正直、迷ったが、利用に注意が十分注意が必要なマストドンインスタンス一覧も掲示する


ユーザー登録する前の準備


・マストドン専用のメールアドレスを用意する

・英数記号を全て組み合わせ、完全にランダムなパスワードを生成する

Google先生で、「パスワードジェネレーター」で検索し、気に入ったサービスを使うのも1つの手だろう。ただし、パスワードジェネレーターで生成された文字列に手で修正を加えるとなおいい。

・もし、IPアドレスを複数所有しているのなら、メインでないIPアドレスを使用すべきである。

・登録対象インスタンスについての利用規約またはプライバシーポリシーを確認する。

・登録対象インスタンスのドメイン名を確認する 適切なWHOIS検索サイトを使い、日本の会社の所有かを調べる

・同様に連絡先メールアドレスを控えておく 連絡先メールアドレスが無い場合は登録を見送った方がいい

 当然、gmail のようなフリーメアドを使っている所は論外である。

 良いのは、.co.jpドメインのメアド、次に、.jpドメインのメアド、最低でもプロバイダーが回線契約者のにみに発行してるメアドである。

・マストドンのインスタンスのドメイン所有者とマストドンの管理者の関係について調べる。

・カッコイイドメイン名のマストドンURLを得るために、運営者が日頃使ってるドメインと違っていることが多々ある

 ここでもWHOISを使用し、運営者の整合性を確認する

・運営者の所在地(住所)・メールアドレス・実名氏名など、トラブル発生時に対応窓口があるかをしっかり確認する。


上記条件が全て満たされた場合は、ある程度のリスクを承知で利用登録し、インスタンスの特徴をつかんでから参加(メッセージ投稿)することがいいだろう。

上記条件を1つでも満たさないインスタンスには登録すべきでない

特にトラブル発生時に窓口が無ければどうしようもなくなるので、この点は特に重要である


利用にあたって、十分な準備と精査が必要であるマストドンインスタンスのリンク集


日本 Mastodon インスタンス一覧

日本のマストドン インスタンス一覧

日本のマストドンインスタンスの一覧

マストドンインスタンスリンク集