質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.39%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Firebase Authentication

Firebase Authenticationは、Firebaseを利用したユーザーの認証機能です。バックエンドサービス、SDK、アプリでのユーザー認証に使用できるUIライブラリが用意されています。

Q&A

0回答

146閲覧

自分の書いたFirebaseのsecurity ruleが本当に安全か知りたい、アドバイスをいただきたい

KosKos

総合スコア0

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Firebase Authentication

Firebase Authenticationは、Firebaseを利用したユーザーの認証機能です。バックエンドサービス、SDK、アプリでのユーザー認証に使用できるUIライブラリが用意されています。

0グッド

1クリップ

投稿2024/04/01 08:31

実現したいこと

自己開発のマッチングアプリの開発にfirebaseを使っています。リリースするにあたり、セキュリティが本当に安全かどうかを調べたいです。

発生している問題・分からないこと

自己流で書いてみたのですが、いまいち自分のコードの安全性に自信が持てません。アドバイスなど頂けたらありがたいです。Security ruleと主にfirebaseの情報に変更が起こるところのソースコードを載せておきます。他に必要なソースコードがございましたら教えて頂けたらありがたいです。

該当のソースコード

Security

1rules_version = '2'; 2service cloud.firestore { 3 match /databases/{database}/documents { 4 5 // 切り出した関数の記述 6 function isAuthenticated() { // 条件 1 7 return request.auth != null; 8 } 9 10 function isUserAuthenticated(userId) { // 条件 1 かつ 条件 2 11 return isAuthenticated() && userId == request.auth.uid; 12 } 13 14 // function isAdmin() { 15 // return isAuthenticated() && request.auth.token.admin == true; // Assuming 'admin' is a custom claim you've set 16 // } 17 18 // ユーザーデータのスキーマ検証 19 function isValidUser(user) { 20 return user.size() == 3 21 && 'createdAt' in user && user.createdAt is timestamp 22 && 'email' in user && user.email is string 23 && 'userId' in user && user.userId is string; 24 } 25 26 27 function isValidUserFS(user) { 28 return user.size() == 12 29 && 'bio' in user && user.bio is string 30 && 'cur_matching' in user && user.cur_matching is string 31 && 'done' in user && user.done is bool 32 && 'facebook' in user && user.facebook is string 33 && 'imageLink' in user && user.imageLink is string 34 && 'instagram' in user && user.instagram is string 35 && 'matchings' in user && user.matchings is list 36 && 'phone' in user && user.phone is string 37 && 'preference' in user && user.preference is string 38 && 'sex' in user && user.sex is string 39 && 'username' in user && user.username is string 40 && 'wait' in user && user.wait is bool; 41 } 42 43 // ルールの記述 44 match /users/{userId} { 45 46 // ユーザー情報の取得のルール 47 allow get: if isUserAuthenticated(userId); 48 49 // ユーザー情報の作成のルール 50 allow create: if isUserAuthenticated(userId) 51 // スキーマ検証 52 && isValidUser(request.resource.data) 53 // データのバリデーション 54 && request.resource.data.createdAt == request.time 55 && request.resource.data.userId == userId; 56 57 } 58 59 match /Users/{email} { 60 allow read: if isAuthenticated(); 61 62 allow create: if isAuthenticated() && isValidUserFS(request.resource.data); 63 64 allow update: if isAuthenticated() && isValidUserFS(request.resource.data); 65 } 66 67 match /Female_match_stack/Counter { 68 // Rules for 'Counter' document 69 allow read, update: if isAuthenticated(); 70 } 71 72 match /Female_match_stack/{document=**} { 73 allow read: if isAuthenticated(); // Only authenticated users can read 74 75 // Allow updating only the stack array, and only allow adding the user's own email 76 allow update: if request.auth != null && 77 request.resource.data.stack.size() == resource.data.stack.size() + 1 && 78 request.resource.data.stack[request.resource.data.stack.size() - 1] == request.auth.token.email; 79 80 allow create: if isAuthenticated(); 81 } 82 83 match /Male_match_stack/Counter { 84 // Rules for 'Counter' document 85 allow read, update: if isAuthenticated(); 86 } 87 88 match /Male_match_stack/{document=**} { 89 // Rules for all documents under Male_match_stack other than 'Counter' 90 allow read: if isAuthenticated(); // Only authenticated users can read 91 92 // Allow updates only if adding to 'stack' with the user's own email 93 allow update: if request.auth != null && 94 request.resource.data.stack.size() == resource.data.stack.size() + 1 && 95 request.resource.data.stack[request.resource.data.stack.size() - 1] == request.auth.token.email; 96 97 allow create: if isAuthenticated(); 98 } 99 } 100}

Flutter

1Future<void> editCondition() async { 2 User? currentUser = _auth.currentUser; 3 if (currentUser == null || currentUser.email == null) { 4 return; 5 } 6 DocumentSnapshot userDoc = await _firestore.collection('Users').doc(currentUser.email).get(); 7 DocumentSnapshot counterDoc = await _firestore.collection('Male_match_stack').doc('Counter').get(); 8 9 String gender = userDoc['sex']; 10 String collectionName = gender == 'male' ? 'Male_match_stack' : 'Female_match_stack'; 11 12 await _firestore.collection(collectionName).doc(counterDoc['num'].toString()).update({ 13 'stack': FieldValue.arrayUnion([currentUser.email]) 14 }); 15 await _firestore.collection('Users').doc(currentUser.email).update({'wait': true}); 16 } 17 18 Future<void> makeMatch() async{ 19 CollectionReference counts = FirebaseFirestore.instance.collection('Male_match_stack'); 20 final counter = await counts.doc('Counter').get(); 21 final cur_cnt = counter.get('num'); 22 CollectionReference males = FirebaseFirestore.instance.collection('Male_match_stack'); 23 final male = await males.doc(cur_cnt.toString()).get(); 24 final maleStack = male.get('stack'); 25 int maleLeng = maleStack.length; 26 CollectionReference females = FirebaseFirestore.instance.collection('Female_match_stack'); 27 final female = await females.doc(cur_cnt.toString()).get(); 28 final femaleStack = female.get('stack'); 29 int femaleLeng = femaleStack.length; 30 final new_cnt = cur_cnt + 1; 31 FirebaseFirestore.instance.collection('Male_match_stack').doc('Counter').update({ 32 'num': new_cnt 33 }); 34 FirebaseFirestore.instance.collection('Female_match_stack').doc('Counter').update({ 35 'num': new_cnt 36 }); 37 if (maleLeng.isOdd){ 38 maleLeng -= 1; 39 FirebaseFirestore.instance.collection('Male_match_stack').doc(new_cnt.toString()).set({ 40 'stack': [maleStack.last] 41 }); 42 } else { 43 FirebaseFirestore.instance.collection('Male_match_stack').doc(new_cnt.toString()).set({ 44 'stack': [] 45 }); 46 } 47 if (femaleLeng.isOdd){ 48 femaleLeng -= 1; 49 FirebaseFirestore.instance.collection('Female_match_stack').doc(new_cnt.toString()).set({ 50 'stack': [femaleStack.last] 51 }); 52 } else { 53 FirebaseFirestore.instance.collection('Female_match_stack').doc(new_cnt.toString()).set({ 54 'stack': [] 55 }); 56 } 57 if (maleLeng>1){ 58 for (int i = 0; i<(maleLeng/2); i++){ 59 FirebaseFirestore.instance.collection('Users').doc(maleStack.elementAt(i)).update({ 60 'cur_matching': maleStack.elementAt(maleLeng-1-i), 61 'matchings': FieldValue.arrayUnion([maleStack.elementAt(maleLeng-1-i)]), 62 'wait': false, 63 'done': false 64 }); 65 FirebaseFirestore.instance.collection('Users').doc(maleStack.elementAt(maleLeng-1-i)).update({ 66 'cur_matching': maleStack.elementAt(i), 67 'matchings': FieldValue.arrayUnion([maleStack.elementAt(i)]), 68 'wait': false, 69 'done': false 70 }); 71 } 72 } 73 if (femaleLeng>1){ 74 for (int i = 0; i<(femaleLeng/2); i++){ 75 FirebaseFirestore.instance.collection('Users').doc(femaleStack.elementAt(i)).update({ 76 'cur_matching': femaleStack.elementAt(femaleLeng-1-i), 77 'matchings': FieldValue.arrayUnion([femaleStack.elementAt(femaleLeng-1-i)]), 78 'wait': false, 79 'done': false 80 }); 81 FirebaseFirestore.instance.collection('Users').doc(femaleStack.elementAt(femaleLeng-1-i)).update({ 82 'cur_matching': femaleStack.elementAt(i), 83 'matchings': FieldValue.arrayUnion([femaleStack.elementAt(i)]), 84 'wait': false, 85 'done': false 86 }); 87 } 88 } 89 }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

何個かsecurity ruleの書き方テンプレートなどをググってみた。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問