Parseサーバーのセキュリティ
皆さんこんにちは!今回はBack4AppでParse Serverを使用する際のセキュリティについてお話します。セキュリティは開発者を喜ばせる話題ではないので、とても簡潔で直接的な内容にします。私がここで意図しているのは、プロダクションアプリにする前にアプリをレビューするための簡単なセキュリティチェックリストを提供することです。
Parse・セキュリティ・メカニズム
アプリに適切なセキュリティアクセスを設定するためには、まず、Parseの基本的なセキュリティメカニズムの概念、デフォルトのParseクラス、および認証メカニズムについて理解する必要があります。
1-デフォルト・クラスのParse
Parseはデフォルトで3つのクラスを作成します:Users、Roles、Sessionsです。これらのクラスはバックエンド全体と完全に統合されており、アプリを保護するための認証メカニズムを設定する際にも便利です。
ユーザー
ParseはParse.Userという
特殊なユーザークラスを提供し、 ユーザーアカウント管理に必要な機能の多くを自動的に処理します。
Parse.User
クラスはデフォルトでセキュリティ保護されています。Parse.Userに
保存されたデータは、そのユーザのみが変更することができます。デフォルトでは、データはどのクライアントからも読み取ることができます。そのため、Parse.User
オブジェクトの中には、認証されて変更できるものもあれば、読み取り専用のものもあります。
役割
Roleは、ユーザやその他のRoleを新しいRoleに関連付けることができるクラスです。Roleを作成すると、CLPやACLを使って、そのRoleがアプリ内でアクセスするものを定義することができます。
セッション
User
login メソッドでユーザーをログインすると、Parse は自動的に新しい制限のないSession
オブジェクトを Parse Server に作成します。サインアップや Facebook/Twitter ログインの場合も同様です。
2-Parse認証メカニズム
Parseのデータアクセスについては、2つの異なるレベルでアプリのセキュリティを制御することができます:
- クラス/テーブル – CLP(クラス・レベル権限)を使用して、新しいカラムの作成とクラス全体への一般的なデータ・アクセスを制限します;
- オブジェクト- ACL(アクセス制御リスト)を使用して、特定のオブジェクトのアクセスを制御する;
クラス・レベル権限 – CLP
クラス・レベルのパーミッションは、クラスとそのすべてのオブジェクトのアクセスを制御するメカニズムです。CLP を使用すると、ロール、ユーザ、またはポインタへの読み書きアクセスを設定できます。
このメカニズムを使って、以下の操作へのアクセスを制限することができる:
- 読む
- Get – 指定された ObjectId のオブジェクト情報を取得します;
- Find – このクラス内のすべてのオブジェクトを検索します(ObjectID は必要ありません);
- Count – オブジェクトのクラス総数;
- 書く
- Create – 新しいオブジェクトを作成します;
- Update – 既存のオブジェクトを更新する
- Delete – 既存のオブジェクトを削除する
- 追加
- フィールドの追加 – このクラスに新しい列を作成します;
これらの設定オプションにアクセスするには、右上のクイックメニューにある小さな盾のアイコンをクリックします。
盾のアイコンをクリックすると、読み取り/書き込みオプションが利用可能なだけのシンプルなメニューが表示されます。ウィンドウの右上のアイコンをクリックすると、高度なCLP設定にアクセスできます。
すると、完全なCLPコンフィギュレーション・ウィンドウが表示されます。
アクセス制御リスト – ACL
アクセス制御リストを使用すると、指定されたクラスの各オブジェクトへのアクセスを異なる方法で制御できます。オブジェクトに対してACL を作成し、役割またはユーザごとにアクセス(読み取り/書き込み)を構成できます。
ParseはRoleを作成する際に常にACLを要求します。そのため、最初のRoleを作成するにはユーザーが必要になる。アプリの最初のRoleを作成するために、rootユーザーを作成しましょう。このユーザーは、これらのRoleを編集できる唯一のユーザーになります。
まず、ユーザー・テーブルにユーザー名とパスワードを入力するだけで、ルート・ユーザーを作成できる。
次に、ルートユーザのObjectIdをコピーし、Role Classに移動します。新しいRoleを作成し、ACLフィールドをダブルクリックしてACLを作成する。今回は、rootユーザーにこのACLの読み書きを許可するので、ACLにrootユーザーのObjectIDを記入して保存しよう。
このステップの後、このRoleにAdminという名前を付けて、AlexとAlyssonというユーザを関連付けましょう。RoleクラスはUserクラスとリレーションを持っているので、リレーションの概要をクリックして、このリレーションに追加したいユーザのObjectIDを追加します。
これで、新しいロールを作成したり、新しいACLや CLP に属性を設定したりするために使用できる、2 人のユーザを持つロール管理者ができました。
セキュリティ・アプリ・チェックリスト
Parseセキュリティの主なコンセプトはご理解いただけたと思うので、あなたのアプリをよりセキュアにするためのアドバイスをいくつか提案したい。
1-マスターキーを安全に保管する
マスターキーは、他のすべてのセキュリティレイヤーをバイパスするためのParseメカニズムである。アプリのマスター・キーを持つことは、サーバーのルート・アクセスを持つようなものだ。
そのため、このキーを保護し、必要なときにクラウド・コード経由でのみキーを使用する必要があります。フロントエンドのコードで使用するのは避けるべきです。誰かが逆コンパイルしたり、JSの場合はソースを表示してキーをコピーすることができるからです。
もう1つのアドバイスは、クラウド・コードでこのキーを使用する場合、(クラウド・コードの一部である)キーをパブリック・コード・リポジトリにコミットしないようにすることだ。
2-クライアント・クラス作成のチェックを外す
Back4Appで新しいAppを作成すると、Parse Key allowClientClassCreationが有効になります。つまり、AppIDとClient Keyがあれば誰でもデータベースに新しいクラスを作成することができる。
この設定は、Back4Appのサーバー設定->コア設定->設定メニューオプションで変更できます。
下にスクロールして、以下のように “Allow Client Class Creation “オプションのチェックを外してください。
アプリの開発中はこのオプションを有効にしておき、開発終了後にこのオプションを外すことをお勧めする。
3-役割構造を作る
ACLのセクションで説明したように、Role Structureを構築することで、すべてのアプリクラスとオブジェクトに対するアクセスをより適切にコントロールすることができる。例えば、Uber-Clone-Appを作っていて、3つの主要なアクセスがあるとしよう:管理者、乗客、ドライバー。
4-ユーザとロールにCLPを設定する
User はデフォルトの Parse Class なので、クラス名、REST API キー、App ID があれば、誰でも curl コマンドひとつですべてのユーザーリストをリクエストできる:
curl -X GET -H "X-Parse-Application-Id:FyebII2zNpA2i9DdZ8froWna9vIvJMcgjfmjS0iK" -H "X-Parse-REST-API-Key: hluEgfZ084RdR0MyyE8Y9v4RwsOsTIWlJeCc4qGw" https://parseapi.back4app.com/users
そしてユーザーリストを取得する:
CLP を作成し、ユーザ・テーブルを読み書きできるユーザを制限することで、これを回避することができます(ACL を使用して保護することも可能です)。この場合、管理者ユーザだけがユーザ・リストを読むことができるようにします。
ロール・クラスと同様の処理を行い、完全なクラスを読む必要のないロール/ユーザーからアクセスを削除することができます。
Session クラスはデフォルトで保護されています。なぜなら、全てのSession
オブジェクトは、そのユーザのみが読み書きできる、自動的に作成された ACL を持っているからです。
5-固定クラスを読み取り専用にする
Parse Dashboard経由でのみ変更したいテーブルやクラスがある場合は、CLPを使って読み取り専用にすることができます。私の場合、Uber-Clone-Appが動作する都市を定義するクラスを作りました。
このクラスはParseダッシュボード経由でのみ変更したいので、他のすべてのロールから書き込みアクセス権を削除します。
6-一般的なCLPおよびACLに関する助言
アプリ内のほとんどのクラスは、いくつかのセキュリティが容易なカテゴリのいずれかに分類されます。完全に公開されたデータに対しては、クラスレベルのパーミッションを使ってテーブルをロックし、誰も読み書きできないようにすることができます。完全にプライベートなデータについては、ACLを使って、そのデータを所有するユーザーだけが読めるようにすることができる。
しかし時折、完全公開や完全非公開のデータを望まない状況に遭遇することがある。例えば、ソーシャルアプリで、あるユーザーのデータを、そのユーザーが承認した友人だけが閲覧できるようにする場合です。このような場合、このガイドで説明するテクニックを組み合わせて、希望する共有ルールを実現する必要があります。
詳しくはACLの作成方法のビデオをご覧ください。
7-セッションの長さを設定する。
非常に機密性の高い情報を含むアプリ(銀行アプリ、ヘルスケアアプリ)を開発していて、短時間でユーザーをログアウトする必要がある場合。
セッションの長さを制限するには、サーバー設定->カスタムアプリ設定に進みます。
カスタムParseオプションのテキストボックスで、セッションの長さを秒単位で定義します。下の例では、セッションの長さを10分としています。その後、保存をクリックします。
8-httpsとSSLの使用
httpsは、クライアントのブラウザからサーバーに情報を転送するための安全なプロトコルです。ハッカーがMITMのような攻撃で機密情報にアクセスするのを防ぐために必要です。
ここでは、Http over Https を使用して Parse サーバーと接続することをお勧めします。以下は、Parse との JS 接続を使用した例で、https を正しく使用してアクティブな接続を確立する方法を示しています。https:// の代わりに http:// を使用するのは間違った方法です。
Parse.initialize("APP_ID", "JS_KEY"); Parse.serverURL='https://parseapi.back4app.com/'
Back4App Webhostingをご利用の場合、Back4Appがデフォルトでhttps接続を提供していることにご注意ください(通話にはhttps:// を使用する必要があります!)。
しかし、独自ドメイン名を使用してBack4Appサーバーにリダイレクトする場合は、SSL証明書が有効で適切にインストールされていること、そしてhttpsを使用してBack4Appにリダイレクトしていることを確認してください。
最後の言葉
Back4AppとParseは、クラウド上でデータを保護する様々な方法を提供します。アプリを構築し、保存するデータの種類を評価しながら、どの実装を選択するかを決定することができます。
これらのツールを使って、アプリのデータとユーザーのデータを安全に保つためにできることをすべて行ってください。一緒に、ウェブをより安全な場所にしましょう。