MisskeyのプラグインAPIとそのリスクの理解

 この記事は実際にとあるインスタンスで発生した事例を基にMisskeyのプラグインAPI(主にMk:apiExternal)に潜む危険性を解説します。この記事は特定個人を攻撃することを目的として作成されていません。
 また、ここで紹介されている情報はすでに知られている情報であり、隠す意味がないと考え、注意喚起を目的として作成しています。


事例

内容

 今回はぼすきーというインスタンスで実際に発生した事例を紹介します。このインスタンスは一般公開がされており、誰でも登録・閲覧をすることができます。
 そして、そのインスタンスに"匿名ぼ民"というアカウントが登録されました。このアカウントはノートの代理投稿が可能なbotであり、Play機能を使った投稿フォームにノート内容を入力することで匿名ぼ民という代理アカウントを通して匿名投稿をすることが可能でした。

このアカウント、 @anon_vomin@voskey.icalo.net から匿名で投稿ができるPlayを公開しました https://voskey.icalo.net/play/9mlnixen0v ※アカウントの管理者が投稿者の承認を得ずに投稿を削除する場合があります #匿名ぼ民

https://voskey.icalo.net/notes/9mlno3sf9u より

 しかし、このアカウントはセキュリティ的、またモデレーション上の問題があるとしてモデレーターによって凍結処分を受けました。

モデレーターからのお知らせです。 匿名ぼ民 `@anon_vomin` アカウントについて、セキュリティ・モデレーション面で懸念事項が多く、最悪の場合取り返しの付かないトラブルに発展する恐れがあるため、凍結処理とさせて頂きました。 今後、類似のアカウントは停止する可能性があります。 いつもぼすきーを楽しんでくれてありがとうございます。

https://voskey.icalo.net/notes/9mt7x1v3td より

仕組み

 さて、このPlayはどのような仕組みで動いていたのでしょうか。実際にコードを確認してみるとこのようなコードを見つけることができます。

// データの送信、結果の受信
let api = "(外部サーバーのURL)" // 向こうでもデータのチェックはします
let result = Mk:apiExternal(api, "post" content) // データの送信

 このコードを確認するとわかる通り、Mk:apiExternalを使用して外部サーバーのAPIにリクエストしていることがわかります。
 なお、ここで言う外部サーバーはMisskey APIを実装しているサーバーに限定はされていません。つまり、APIの形式さえ合えばいかなるサーバーに対してもリクエストが送れます。実際にはおおよそ以下の図のような流れでインスタンス上のアカウントで投稿されていると考えます。

匿名ぼ民で使われた構成

 まとめると、PlayというUIを通してAPIを利用して行った投稿リクエストをbotサーバーが受け取り、そのbotサーバーがインスタンスサーバーに投稿を行っていたというわけです。

問題点

 さて、このbotの問題点はどこにあるでしょうか。その回答はモデレーション上の問題が発生しやすいと言う点にあるでしょう。
 想像しやすいシナリオで言うと犯行予告での利用でしょう。このbotで投稿された内容は全てbotサーバーに集約され、匿名化されています。そのため、もし犯行予告などが行われた場合、その内容の発信元の特定が困難になります。こうなるとモデレーション上の懸念が発生します。
 また、このbotサーバーのAPIに直接リクエストを行えばそのインスタンスに登録をせずとも投稿が行えてしまうという点もモデレーション上の問題がありそうです。
 そのほか、匿名であるという点を利用して他者の悪口を言った事例を確認しました。これは周囲の人間に対して不信感を抱く原因を生み出し、お互いに疑心暗鬼になってしまいます。

その他の考えられる懸念

 今回の件とは直接的な関係はありませんが、Mk:apiExternalが外部APIを叩ける事実は、外部サーバーが不正にデータを収集できる可能を提示します。例えば、Playがアクセストークンを利用するものであれば、権限を持ったアクセストークンの収集や、フォロワー限定ノートやダイレクトノートなどを収集できてしまいます。これは秘密の漏洩やなりすましなどのリスクがあります。

アクセストークンとTwitter(現X)の事例に学ぶ

 XがまだTwitterという名前でAPIが無料だった時代の話。TwitterにはTwitter連携ができるアプリで溢れていました。それらの中には「Twitter連携したら乗っ取られるアプリ」というものがありました。それらのアプリの問題は、連携の際にノートの投稿の権限をユーザーに要求し、その権限を悪用していたことにあります。
 MisskeyのアクセストークンもTwitter連携と同様の問題を抱えています。つまり、アクセストークンを他人に教えるということは、自身のMisskeyアカウントの一部の機能が乗っ取られると認識しても良いでしょう。
 だから、アクセストークンの発行管理は慎重に行うべきであり、信頼できるアプリケーション以外には使用していけないわけです。

対策

Misskeyユーザー側

 アクセストークンが必要なPlayの場合、そのPlayがアクセストークンを適切に取り扱っているか確認してください。
 また、Playで一度使ったアクセストークンはPlayを終了する際に破棄してください。アクセストークンの破棄は「アクセストークンの管理」から行えます。
 「アクセストークンの管理」は https://example.com/settings/apps のようなURLからアクセスできます。例えば misskey.io の場合であれば https://misskey.io/settings/apps から、アクセスできるわけです。

サーバー管理者側

 モデレーションとして何かを検知するというのは比較的困難に思えます。ユーザーからの通報を受けてコードを精査し凍結の可否を下すことくらいしかできないでしょう。
 または、すべてのPlayを自動的に検証する方法も存在するとは思います。また、うまいことすべてのPlayのコードを集めて、それぞれに対してMk:apiExternalがあった場合送り先や送るものが適切か、不適切なアクセストークン要求を行っていないかなどを確認するという泥臭い方法はあります。

Play制作者側

 このようなPlayは作らないでください。Playの制作に責任を持ちましょう。
 また、必要なアクセストークンは必要な時に毎度要求するようにしてください。利便性の面ではアクセストークンを毎度要求するのは不便ですが、Mk:saveなどに保存をしないでください。
 Mk:saveなどに保存すると毎回要求しないでも良いので便利ですが、Mk:saveはkeyさえ合っていれば誰でもMk:loadで読み込めます。つまり、アクセストークンが漏洩するリスクがあるわけです。
 MisskeyのMk:save()およびMk:load()ではPlayを跨いだ干渉はできないようです。

最後に

 今回の一件のPlay作者に対して私的な攻撃が行われないことを私は望みます。最後に、ぼすきーのモデレーターの方の対応に感謝します。


この記事が気に入ったらサポートをしてみませんか?