Firebase用户帐户安全与firebaseSimpleLogin [英] Firebase user account security with firebaseSimpleLogin

查看:169
本文介绍了Firebase用户帐户安全与firebaseSimpleLogin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到最好的方法来设计我们的应用程序的安全性,使用firebase



基本问题



我们希望用户的数据安全。我们不希望恶意代理能够访问Firebase数据库中的其他用户的私有数据。这似乎应该有一个解决方案,通过firebaseSimpleLogin,但尽管冲刷文档,我们还没有看到一个。
$ b

具体问题
$ b


  • 我们提供一个包含使用者帐户的应用程式,可以阅读:


    • 自己的数据 b $ b
    • 与所有用户相关的应用范围数据,例如一个模板,所有的用户在他们最初创建他们的账户时都会得到一个
      的副本,其中
      的原始副本是在$ fb db
    • 一部分数据另一个用户,如果
      其他用户明确决定与他们分享,例如
      a游戏他们让他们想让另一个用户拥有一个



  • 现在,用户登录与
    FirebaseSimpleLogin。这是有问题的,因为任何恶意用户
    都可以合法地创建自己的帐户,并使用其帐户的
    电子邮件和密码以恶意脚本登录,并访问
    db



我们考虑的解决方案

1。存储一个user_secret,以确保用户具有合法的访问权限。


  • 受到第二种方法的启发,回答如何设置Firebase安全规则以仅接受来自iOS应用程序


    • 结构看起来像是security-> user_secret-> associated_user或security-> user - > {all_valid_user_secrets}

    • 安全规则:.read:root.child('user_secrets /'+ auth.uid).exists()


  • 我们可以为每个用户存储多个用户密钥,允许从多个已验证的源(iOS应用程序,Web应用程序等)访问


    #1的问题


    • 我们如何限制对安全性的读/写访问儿童?


      • 服务器不存在SimpleLogin
      • 我们不希望这些信息可见,因为恶意用户可能在技​​术上阅读它找到他/她自己的帐户信息,然后用它来仔细阅读其余的数据库


    • 在问题说明中:用户可以合法地生成一个帐户,然后使用这些凭据获得对数据库的恶意访问



    2。临时存储用户密码




    • 用户启动登录

    • 节点服务器生成密码,它在Firebase中受限安全的孩子(服务器可以这样做,因为Firebase Secret允许完全访问)
    • >
    • 用户与应用程序交互。如果由节点服务器编写的安全子节点存在,则Firebase安全规则仅允许读/写访问。

    • 用户启动注销/崩溃/关闭应用程序
    • 节点服务器从受限制的安全子级移除密码

    • 取消对Firebase ref的授权



    • #2的问题 - 此方法的问题在于用户在登录时易受攻击,因为他们的安全信息将存在。 3>。

      3。使用内置的Firebase安全规则




      • 我们希望有一个内置的Firebase解决方案,但还没有找到解决方案解决了上述问题。如果您能指出我们会是一个很棒的。



      我们希望有人能够帮助我们阐明最好的方法,使用我们的想法或其他路线。非常感谢您的帮助。

      解决方案

      您基本上已经要求某人为您的应用程序编写完整的安全模式。如果您在尝试将这些规则应用于这样复杂的结构之前,彻底理解安全规则会更好。 从头到尾对文档进行很好的研究将会使您走很长的路到一个全功能的解决方案。

      我们只关注看起来像是什么核心问题,就是您不确定如何使用客户端安全地进行邀请 - 唯一的解决办法。 (node.js解决方案在这个理解中也应该是显而易见的,考虑到能够创建我们自己的令牌所提供的额外火力)我会在这里做很多假设;数据结构:

       (一个存储被邀请用户的地方)
      / accepted_invites / $ gameid / $ userid / $ uuid / true(一个存储被接受的邀请的地方) / invites / $ game_id / $ uuid /
      / games / $ game_id(我们想邀请用户进入的地方)
      / users / $ user_id(我们为现有用户放置配置文件的地方)
      1)当一个新用户在应用程序中创建一个帐户时,将他们的个人资料写入/ users。

      保护用户/如下:

       users:{
      $ userid:{
      .write:auth.uid === $ userid
      }
      }



      2)邀请用户,创建一个 uuid ,它表示一个不可猜测的id,并将其存储在invites / $ game_id中。

       invites:{
      $ game_id:{
      $ invite_id:{
      //我只能为群组创建邀请我是
      的成员.write:root.child('games /'+ $ game_id +'/ members /'+ auth.uid).exists(),
      .validate:newData.val()=== true
      }
      }



      3)要加入游戏,用户必须先接受访问令牌,证明他们
      知道令牌(因为他们不能读取邀请路径)并将令牌链接到他们的
      帐户ID。

       accepted_invites:{
      $ game_id:这个条目的值是邀请函的uuid。 {
      $ user_id:{
      .write:auth.uid === $ user_id,
      .validate:root.child('invites /'+ $ game_id +'/'+ newData.val())。exists()
      }
      }
      }


      $ b $ 4)如果用户已经接受邀请,或者初始创建并且还没有成员(!data),则用户可以自己写入游戏。 parent()。exists() rule)


       game:{
      $ gid:{
      members:{
      $ uid:{
      .write:auth.uid === $ uid,
      //我可以加入一个组,如果a)我创建它或b)我已经接受邀请
      .validate:!data.parent()。exists()|| root.child('accepted_invites / ()



      $ b code $ + pre>

      另一个enha我们的客户端解决方案的ncement将分配邀请的优先级,它代表何时到期,然后在安全规则中引用该优先级来控制令牌有效期。

      I'm trying to find the best way to design security for our app that uses firebase

      Basic problem

      We want our users’ data to be secure. We don’t want a malicious agent to be able to access other users’ private data on the Firebase db. It seems that there should be a solution for this via firebaseSimpleLogin, but despite scouring the documentation, we haven’t seen one.

      Problem specifics

      • We offer an app with user accounts, and these users have private data
      • Users should only be able to read:
        • their own data
        • app-wide data relevant to all users, e.g. a template that all users get a copy of when they initially create their account, the original copy of which is on the fb db
        • a portion of data of another user, if that other user has explicitly decided to share it with them e.g. a game they made that they want another user to have a copy of
      • Right now, users log in with FirebaseSimpleLogin. This is problematic because any malicious user can create their own account legitimately, and use their account’s e-mail and password to login with a malicious script, and access the db

      Solutions we’ve considered

      1. Store a user_secret to ensure user has legitimate access

      • Inspired by 2nd method in answer to How to setup Firebase security rules to accept connections only from an iOS App
        • The structure would look like security->user_secret->associated_user OR security->user->{all_valid_user_secrets}
        • Security rule: ".read": "root.child('user_secrets/'+auth.uid).exists()"
      • We could store multiple user secret keys per user, allowing access from multiple verified sources (iOS app, web-app, etc)

      Problems with #1

      • How do we restrict write/read access to the security child?
        • SimpleLogin doesn’t exist for servers
        • We don’t want this information visible, as a malicious user could technically read it to find info about his/her own account, and then use that to peruse the rest of the db
      • Same problem as in the problem statement: a user can generate an account legitimately, and then use those credentials to gain malicious access to the db

      2. Temporarily Store User Secret

      • User initiates login
      • Node server generates password, stores it in restricted security child in Firebase (the server would be able to do this, as Firebase Secret allows full access)
      • We authorize firebase client side using Firebase SimpleLogin as we have been
      • The user interacts with the app. Firebase security rules only allow read/write access if the security child written by the node server is present
      • User initiates logout/crashes/closes app
      • Node server removes password from restricted security child
      • Unauthorize Firebase ref as we have been
      • Done

      Problem with #2 - The issue with this method is the user is vulnerable while they’re logged in, as their security information would be present.

      3. Use built in Firebase Security Rules

      • We hoped there was a built in firebase solution, but haven’t found one that solves the resolves the above problem. If you can point us to one that would be terrific.

      We are hoping someone can help shed light on the best approach here, either using our ideas or another route. Thanks so much for your help.

      解决方案

      You've essentially asked for someone to write an entire security schema for your app. It would be better if you understood security rules thoroughly before attempting to apply them to a complex structure like this. A good study of the docs from start to end would take you a long way to a fully functional solution.

      Let's just focus on what seems to be the core problem, which is that you aren't sure how to make invites work securely with a client-only solution. (The node.js solution should also be obvious with this understanding, given the additional firepower provided by being able to create our own tokens) I'll make a lot of assumptions here; just apply these ideas to your current use case as you see fit.

      A data structure:

      /invites/$game_id/$uuid/true  (a place to store invited users)
      /accepted_invites/$gameid/$userid/$uuid/true (a place to store accepted invites)
      /games/$game_id (the place we want to invite users into)
      /users/$user_id (a place where we put profiles for existing users)
      

      1) When a new user creates an account in the app, write their profile into /users. Secure users/ as follows:

      "users": {
         "$userid": {
            ".write": "auth.uid === $userid"
         }
      }
      

      2) To invite a user, create a uuid, which represents an unguessable id, and store it in invites/$game_id. Note that nobody should be able to read this path.

      "invites": {
         "$game_id": {
           "$invite_id": {
              // I can only create an invite for groups I'm a member of
              ".write": "root.child('games/'+$game_id+'/members/'+auth.uid).exists()",
              ".validate": "newData.val() === true"
           }
         }
      }
      

      3) To join a game, a user must first accept the access token, which proves that they know the token (since they can't read the invites path) and links the token to their account id. The value of this entry is the uuid of the invite.

      "accepted_invites": {
         "$game_id": {
            "$user_id": {
               ".write": "auth.uid === $user_id",
               ".validate": "root.child('invites/'+$game_id+'/'+newData.val()).exists()"
            }
         }
      } 
      

      4) A user can write themselves into a game if they have accepted an invite or when it is initially created and there are no members yet (the !data.parent().exists() rule)

      "game": {
         "$gid": {
            "members": {
              "$uid": {
                 ".write": "auth.uid === $uid",
                 // I can join a group if a) I'm creating it or b) I have accepted an invite
                 ".validate": "!data.parent().exists() || root.child('accepted_invites/'+$gid+'/'+auth.uid).exists()"
              }
            }
         }
      }
      

      Another enhancement to our client-side solution would be to assign the invites a priority, which represents when they expire, and then reference that priority in the security rules to control how long the token is valid.

      这篇关于Firebase用户帐户安全与firebaseSimpleLogin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆