2015/06/02

Firebase - セキュリティとFirebase Rules

Firebase公式サイトにあるSecurity&Rulesの翻訳です.
https://www.firebase.com/docs/security/

Security & Rules Quickstart

Firebase provides a flexible, expression-based rules language with JavaScript-like syntax to easily define how your data should be structured and when your data can be read from and written to.
Combined with our login service which allows for easy authentication, you can define who has access to what data and keep all of your user’s personal information secure.
The Security and Firebase Rules live on the Firebase servers and are automatically enforced at all times.

FirebaseはJavaScriptライクな構文でルールを記述できる仕組みを用意しており, データへのRead/Write制御を柔軟で手軽に構築できる.
Firebaseが備えている手軽なログインサービスと組み合わせて, データへのアクセス制御とパーソナルデータをセキュアに保つ.
セキュリティとFirebase RuleはFirebaseサーバ上で動作し, 常に自動でこれらが有効になっている.

Understand the Default Security and Firebase Rules

Security and Firebase Rules are used to determine who has read and write access to your Firebase database as well to ensure the structure of that data. They are found in the Security tab of your Firebase Dashboard. They come in three flavors: .write, .read, and .validate. Here is a quick summary of their purpose:

セキュリティとFirebase Ruleは誰がFirebaseのデータにRead/Writeアクセスできるのかを決定し, またデータ構造を保証する. これらはFirebaseのDashboardにあるSecurityタブから確認できる. これらの情報は.wirte, .read, .validateの3つのキーワードから成る. 下記はそれらキーワード毎の概要である.

Rule Type Description
.read Describes if and when data is allowed to be read by users.
.write Describes if and when data is allowed to be written.
.validate Defines what a correctly formatted value will look like, whether it has child attributes, and the data type.
Rule Type Description
.read ユーザによるデータREADの許容内容を記載する.
.write ユーザによるデータWRITEの許容内容を記載する.
.validate 子要素データの形式やデータタイプのバリデーション記述.

Security and Firebse Rules have a JavaScript-like syntax which makes them easy to work with. By default, your Firebase app has rules which grants every request full read and write permissions to your Firebase:

セキュリティとFirebase RuleはJavaScriptライクなシンタックスで表現される.
デフォルトルールだと, あなたのFirebaseは全ユーザにRead/Writeのフルアクセスを許可している.

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Security and Firebase Rules live on the Firebase servers and are enforced at all times. Every read and write request will only be completed if your rules allow it. With the default rules above, all requests will be permitted.

セキュリティとFirebase RuleはFirebaseサーバ上で動作し, 常に自動でこれらが有効になっている.
全てのRead/Writeリクエストはあなたの記述したルールで許容されたもののみが実行可能となる. デフォルトルールは前述の通りですべてのリクエストを受け入れる.

SECURITY BEHIND THE SCENES
Firebase handles many other security details for you.
Specifically, we use strong 2048 bit keys for our SSL certificates, sign authentication tokens with SHA256 HMAC signatures, and use BCrypt for password storage.

セキュリティの舞台裏
Firebaseは他にも多数のセキュリティ機能を備えている.
具体的にはSSL証明書には2048bit長鍵を使用しており, 認証トークン署名にはSHA256 HMACシグネチャを用いている. さらにパスワードストレージにはBCryptを使用している.

Use Predefined Variables

There are a number of helpful, predefined variables that can be accessed inside a security rule definition. Here is a brief summary of each:

セキュリティルールを定義する際には予め用意された役に立つ変数を使用することができる.

Variable Description
now The current time in milliseconds since Linux epoch. This works particularly well for validating timestamps created with the SDK’s Firebase.ServerValue.TIMESTAMP.
root A RuleDataSnapshot representing the root path in the Firebase database as it exists before the attempted operation.
newData A RuleDataSnapshot representing the data as it would exist after the attempted operation. It includes the new data being written and existing data.
data A RuleDataSnapshot representing the data as it existed before the attempted operation.
$variables A wildcard path used to represent ids and dynamic child keys. auth Represents an authenticated user’s token payload.
Variable Description
now UNIX標準時ベースの現在時刻(msec). この変数はFirebase.ServerValue.TIMESTAMPのタイムスタンプを検証するのに適している.
root Firebaseデータベースのルートパスを表すRuleDataSnapshot. オペレーションの前に存在するデータを指す.
newData Firebaseデータベースの新しいデータを表すRuleDataSnapshot. オペレーションの後に存在するであろうデータを指す.
data Firebaseデータベースの既存データを表すRuleDataSnapshot. オペレーションの前に存在するデータを指す.
$ variables ID, 子要素のKeyを指すワイルドカードパス
auth 認証済みユーザトークンのペイロード

These variables can be used anywhere in your Security and Firebase Rules. For example, the security rules below ensure that data written to the /foo/ node must be a string less than 100 characters:

これらの変数はセキュリティとFirebase Ruleの各所で使用することができる. 例えば, 下記のセキュリティルールは/foo/ ノードへの書き込みにあたり100文字未満であることをバリデートする.

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,
      // /foo is writable by the world
      ".write": true,
      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

Make Your Rules Dynamic

Your Security and Firebase Rules should follow the structure of the data you have stored in your Firebase database. For example, say you are keeping track of a list of messages and that your data looks like this:

セキュリティとFirebase Ruleはあなたが持つFirebase databaseのデータ構造に従ったものとする必要がある.
例えば, メッセージリストをトラッキングするデータ構造は下記のようになる

{
  "messages": {
    "message0": {
      "content": "Hello",
      "timestamp": 1405704370369
    },
    "message1": {
      "content": "Goodbye",
      "date": 1405704395231
    },
    ...
  }
}

Your rules should be structured in a similar manner. We can make use of $ variables in rules which represent dynamic child keys. In addition, we can use .validate rules to ensure our data is properly structured. For example, the $message variable below represents each of the /messages/ node’s children:

これのルールについても同じ構成である必要がある. ルールの中では$変数を使用して直接の子Keyを表現することができる. また正しい構成であるかの確認に.validateルールも使用できる.
例えば, $message変数は下記の/messages/ノード配下の子要素を表現する.

{
  "rules": {
    "messages": {
      "$message": {
        // only messages from the last ten minutes can be read
        ".read": "data.child('timestamp').val() > (now - 600000)",
        // new messages must have a string content and a number timestamp
        ".validate": "newData.hasChildren(['content', 'timestamp']) && newData.child('content').isString() && newData.child('timestamp').isNumber()"
      }
    }
  }
}

Integrate Authentication Rules

Firebase gives you full control over user authentication. Login providers are server-side components that authenticate your users. Choose a built-in login provider for a common authentication use case, or build your own custom login provider to address special login needs.

Firebaseはユーザ認証の古コントロール機能を提供する. サーバサイドコンポーネントとしてユーザ認証を行うログインプロバイダーを提供する. 共通の認証にビルトインのログインプロバイダーを選択するか, 特別なログインの必要性を満たすためにカスタムされたログインプロバイダーを選択できる.

No matter how you authenticate your user, this action defines the auth variable in your Security and Firebase rules. This variable contains the user’s auth payload, which includes that user’s unique identifier (uid), and the name of the provider they logged with. Built-in providers also add provider-specific fields to auth, such as the user’s name. If you implement a custom login provider, you can add your own fields to your user’s auth payload.

あなたが選択した認証方法に関わらず, アクションはセキュリティとFirebase Ruleの中でauth変数として定義される. この変数はユーザ認証のペイロードを含み, ユーザを一意に識別(uid)し, プロバイダーの名前が記録される. ビルトインプロバイダーはユーザの名前などプロバイダー固有の領域をauthへ追加する.

Typically, you’ll store all of your users in a single users node whose children are the uid values for every user. If you wanted to restrict access to this data such that only the logged-in user can see their own data, your rules would look something like this:

一般的に, 全てのユーザを単一のusersノードにまとめ, 各ユーザはuidの値として保持する. もしログインしたユーザにのみデータへのアクセスを制限したい場合は次のようなルールになる.

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "auth != null && auth.uid == $uid"
      }
    }
  }
}