22

I am designing an application (let's call it a TodoList app) based on VueJs (for the UI) + NodeJs (for the backend, which will run in Google Cloud Platform) + Firestore (for the auth + database).

I have wandered through the huge documentation of Google (sometimes redundant!) to achieve something that should work but I am not sure it's production-proof.

Situation:

  • A user has signed-in on my VueJs app thanks to the password-based authentication of Firebase (and the user's credentials, including his accessToken, are stored in my Vuex store).
  • The Firebase Admin SDK is running on my backend.
  • My VueJs app is requesting my backend.
  • The backend verifies the accessToken sent in the client-side request
  • It is my backend that request my Firestore database thanks to the Admin SDK

I have set some security rules on my Firestore database:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId}/{document=**} {
      allow read, write: if request.auth.uid == userId;
    }
  }
}

so that I don't want any logged users to access data from another user.

Question:

As the Firebase Admin SDK has full privilege on my Firestore database, how can I make sure there won't be any security issues. For now, I am just verifying the accessToken sent in the request to my backend, but ... something makes me feel wrong with this!

Code:

On client-side:

auth.onAuthStateChanged((user) => {
  if (user) {
    // Save the user credentials
  }
}

On server-side:

// idToken comes from the client app (shown above)
// ...
admin.auth().verifyIdToken(idToken)
  .then(function(decodedToken) {
    var uid = decodedToken.uid;
    // Retrieve or add some data in /users/{userId}/{document=**}
  }).catch(function(error) {
    // Handle error
  });

As you can see, once I validate the accessToken and retrieve the uid, I can do anything on my database.

References

Thanks for your help!

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
m.lapeyre
  • 477
  • 7
  • 18
  • 2
    What's the reason for going through a custom backend in this scenario? Why not get your client to directly access Firestore? Rules will be fully enforce in that case. – Hiranya Jayathilaka Mar 23 '18 at 16:42
  • I need to perform some computations on the data retrieved from Firestore. Hence I prefer to have a backend that will do the hard work :) – m.lapeyre Mar 23 '18 at 17:25
  • I noticed https://firebase.google.com/docs/database/admin/start#authenticate-with-limited-privileges. I may find a way to pass the user's id through my backend to be matched with the security rules (like if my client directly accesses firestore) – m.lapeyre Mar 23 '18 at 17:36
  • That only works for Realtime Database. Firestore APIs in Admin SDK do not enforce rules at the moment. – Hiranya Jayathilaka Mar 23 '18 at 17:52
  • 1
    Hum, so there is no way to have a backend service emulating a user to limit access to a server process, isn't it? A (bad) idea would be to initialize a firebaseApp with `databaseAuthVariableOverride: {uid: "user-uid"}` for each client request to my backend before requesting the database ... – m.lapeyre Mar 23 '18 at 20:03
  • Or, instead of using Admin SDK for server development, I can use the nodeJS SDK of Cloud Firestore in my server. Is there a way to pass through the credentials of the user from the client to the server and then to firebase ? – m.lapeyre Mar 23 '18 at 20:07
  • When it comes to Firestore in the server side, `Admin SDK == Firestore Node.js SDK`. Currently there's no way to scope Firestore down to an individual user in server-side. `databaseAuthVariableOverride` only works for Realtime Database. This requirement is in the Firebase/Firestore roadmap. It's just not supported as yet. – Hiranya Jayathilaka Mar 23 '18 at 21:24
  • Thank you @HiranyaJayathilaka, I think it's clear :) I will implement my own security layer, along with verifyIdToken(). Thanks! – m.lapeyre Mar 23 '18 at 21:54
  • Possible duplicate of [Firestore - security rules for users within companies](https://stackoverflow.com/questions/49183732/firestore-security-rules-for-users-within-companies) – Nth.gol Aug 09 '18 at 15:00
  • Any update on whether this is available for Firestore yet? – MadMac Jan 20 '21 at 19:56

2 Answers2

27

The admin SDK will always have full access to the database.

Since the client is never accessing Firebase directly, you should totally disable access to all documents. Your API will still have access

match /{document=**} {
  allow read, write: if false;
}
Lane
  • 6,532
  • 5
  • 28
  • 27
  • Tested: The Admin SDK doesn't work on Firestore Emulator unless the security rules all set to true: https://github.com/firebase/firebase-tools/issues/1363#issuecomment-635834971 – Antonio Ooi May 29 '20 at 08:22
  • @AntonioOoi are you sure? I did not test on emulator but the live version is working fine with me – MSaudi Apr 09 '21 at 11:23
  • At least recent versions of the Firestore Emulator allow full access for the admin sdk when set up correctly. – ThdK Feb 05 '22 at 11:37
0

I think after verify access token from client-side, you can send uid in resource of firestore-admin, and firestore rules would like this:

allow read, write: if request.resource.data.uid == userId;
Robert
  • 5,278
  • 43
  • 65
  • 115
TaiDT
  • 1