Firebaseの技術情報サイト

Firebaseの技術情報サイト

Firebase活用の為の技術情報サイトです

Firebaseストレージのセキュリティルール

Firebase ストレージのセキュリティルール

Firebase ストレージを Web ブラウザ(クライアント)側から使う場合も、Firebase データベース(Cloud Firestore)を利用する場合と同様にセキュリティルールを設定してアクセスの権限を管理する必要があります。

この記事では、Firebase ストレージを利用する際のセキュリティルールの設定のやり方を紹介します。

基本的はデータベースと同じです!

Firebase ストレージのセキュリティルールの基本は Firebase のデータベース(Cloud Firestore)と同じです。従って、Firebase のデータベース(Cloud Firestore)のセキュリティルールを書いた事があれば同じ容量で設定できます。

Firebase のデータベースのセキュリティルールの記事でも書いていますが、セキュリティルールの基本は以下の3点です。

  • ユーザーによる設定
  • アクセスする対象による設定
  • アクセスタイプによる設定

です。

ユーザによる設定

ユーザーによる設定の場合は、Firebase のユーザー認証機能を利用してユーザー認証(ログイン)の情報である、ユーザー ID(uid)や E-Mail アドレスなどを利用してルールを設定します。この部分は、Firebase のデータベース(Cloud Firestore)の場合と全く同じ要領で設定できます。

アクセス対象による設定

アクセスに対象による設定は、Firebase データベース(Cloud Firestore)の場合、データベースのコレクションやドキュメントでしたが、Firebase ストレージの場合は、バケット(フォルダ)やファイルが対象になります。対象は違ってきますが、ルールの書き方はほぼ同じです。

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPathes=**} {
        allow read, write: if false;
    }
    match /posts/{imageId} {
      allow read;
      allow write: if request.auth.uid == "xxxxxxx";
    }
    match /memberonly/{restricted} {
      allow read: if request.auth.uid != null;
      allow write: if request.auth.uid == "xxxxxxx";
    }
}

上の例では、基本的に全てのアクセスは許可しない設定にしておいて、必要なアクセスのみを許可するように構成されています。 許可するのは、全ての利用者に「/posts」のフォルダの下のファイルの読み込みを許可しています。書き込みは、ユーザー ID(uid)が「xxxxxxx」のユーザのみ許可するような設定です。これは基本的にサイトの管理者になります。 このルールの場合、Web サイトの管理者がアクセスするファイルを Firebase ストレージにアップロードして、一般の利用者は自由にそのファイルにアクセスできるという設定です。 別のフォルダ「restricted」は、Firebase のユーザー認証(ログイン)をした利用者ならば誰でも読み込みが可能になります。つまり、会員に限ったアクセスなどを設定したい場合はこのようなセキュリティルールになります。

アクセスタイプによる設定

アクセスのタイプも、Firebase のデータベース(Cloud Firestore)と同じです。基本は、「読み込み(read)」と「書き込み(write)」になりますが、さらに細かく、「新規作成」「更新」「削除」分けることもできます。

Firebase のセキュリティルールの制限

Firebase ストレージのセキュリティルールを設定する場合に気をつける点があります。 これは、別の記事で Firebase ストレージの読み込みの記事でも触れていますが、「getDownloadURL()」で取得した URL でダウンロードアクセスする際には、セキュリティールールは適用されません。 つまり、URL を知っていれば、セキュリティルールの設定にかかわらず誰でもダウンロードは可能ということです。この部分は勘違いが多いので注意が必要です。

セキュリティルールは、「getDownloadURL()」を利用して、URL を取得する場合には適用されます。この場合、アクセスが許可されていない利用者は URL を取得する事はできません。

問題は、この URL にはアクセスをするための「トークン」が含まれていますが、この URL は基本的に毎回同じ URL が発行されます。つまり、誰かが URL を取得していて、そのリンクを別の人と共有している場合には、アクセスの許可がない場合でもファイルをダウンロードできるという問題が発生します。 理由は簡単でダウンロードを実際に行うのはブラウザでプログラムではないのが大きな理由です。

従って、誰にでも公開して問題のないファイルの場合には大きな問題にはなりませんが、特定の人のみにファイルを公開したい場合には注意が必要です。現在の Firebase の API では、フロントエンドでの対策は基本的にありません。最も簡単な対策は、バックエンドで期限付きの URL を発行する仕組みを作って、その URL を提供するようにすると問題を最小限にする事ができます。 この場合も、URL が有効である限り、その URL を使えば誰でもダウンロードできる点は同じです。しかし、有効期限が設定できるので、長期間に渡って第三者がダウンロードできる状態にはなりません。

書き込み権限の注意

書き込みの権限があると、Firebase のストレージにファイルをアップロードできます。この権限を設定する場合には、必要最低限にする事が重要です。例えば全ての利用者にこの権限を設定する場合は、誰でもファイルをアップロードできる事になるので、Firebase のストレージの利用容量には注意を払う必要があります。Firebase の利用料金は実際に使用している容量も課金対象なので、大量のデータがアップロードされる可能性があるので、気をつけて見ていないと予想外の利用料金を請求されることもあり得るということです。

無難な使い方は、Firebase にログインした利用者に限定するなどすると、悪意でデータをアップロードされる可能性は少なくなると思われます。サービス上必要な場合でも、使用容量に気をつけるのは重要です。

バックエンドを介しての利用

ダウンロードの権限のところで触れていますが、Firebase のストレージの機能を使う場合、少し面倒でもバックエンドを介して Firebase のストレージにアクセスする方がセキュリティ上や運用上の観点で良い場合があります。

例えば、容量の大きなファイルのアップロードは受け付けない様にしたり、警告を送付するようにしたりする場合には、直接 Firebase のストレージにアップロードをせずにバックエンドの処理を通すと事前にチェックする事が可能です。また、期限付きの URL を取得したり、フロントエンドではできない事も可能になります。

また、バックエンドの処理でアクセスの権限を設定できるので、慣れないセキュリティルールで複雑なルールを設定するより便利な場合も多くなります。シンプルな利用ではバックエンドの処理は不要の場合が多いですが、少し複雑な処理や機能上の要求がある場合はバックエンドの実装も検討してみると便利です。

Fiebase のデータベースの場合と同じですが、Fiebase ストレージの管理機能が必要な場合も、フロントエンドからセキュリティルールで管理者の権限を設定して行うよりは、専用の管理用の PC から管理用のアプリを動かして管理する方がセキュリティ上はより安全です。

まとめ

Firebase のストレージを利用する際のセキュリティルールの設定について紹介してみました。セキュリティルール自体は Firebase のデータベース(Cloud Firestore)と同じ容量で設定ができます。大きな違いは、Firebase のデータベース(Cloud Firestore)の場合、コレクションやドキュメントがアクセスの対象になりますが、Firebase ストレージの場合は、バケット(フォルダ)やファイルが対象になります。それ以外は基本的に同じです。

注意点は繰り返しになりますが、「getDownloadURL()」で取得するリンク(URL)にはセキュリティルールの設定は適用されません。リンク(URL)を知っていれば、セキュリティルールの設定に関わらずダウンロードが可能になりますので十分に理解した上で使う必要があります。

Firebase のデータベース(Cloud Firestore)の時と同様に、管理機能などは Firebase admin SDK を活用した、管理アプリにするとよりセキュリティ上安全な管理が可能になります。

さらに、実装する機能によっては、Firebase のストレージのアクセスをバックエンドを介して実装した方がより良いサービスになる場合もありますので必要があれば検討すると良いかと思います。

大抵のセキュリティルールのコンセプトは Firebase のデータベースの設定に似たものになる場合が多いので、セキュリティルールの基本部分は共用して、アクセスの対象となる部分だけを入れ替えればルールの大枠は共通で使用できます。