totallytotallyamazing
totallytotallyamazing

Reputation: 2923

Firestore security rules for users to be able to delete their profiles in react native

In the same main users directory, I'm duplicating a user profile (with a new name), before deleting the original user directory. My current working rules do not seem to be secure [BELOW]. Can anyone please tell me what vulnerabilities I might be leaving my react native expo app open to with these Firebase Security Rules or if some aspects are unnecessary:

match /users/{userId} {
    allow read: if request.auth != null;

    allow create: if request.auth != null 
    && request.auth.uid == request.resource.data.id;

    allow update: if request.auth != null 
    && request.auth.uid == request.resource.data.id 
    && request.auth.uid == userId;

    allow delete: if request.auth != null;
}

***** EDIT:

After Frank van Puffelen's sound advice everything works other than... see: "πŸ‘ˆ" [BELOW]. This rule failure is due to my renaming the duplicated file in the same directory. Any advice on a different approach would be appreciated.:

match /users/{userId} {
    allow read: if request.auth != null;
      
    // Frank van Puffelen’s sound suggestions [BELOW]
    allow create: if request.auth != null 
    && request.auth.uid == request.resource.data.id
    && request.auth.uid == userId; // πŸ‘ˆ ***** this fails my duplication *****

    allow update: if request.auth != null 
    && request.auth.uid == request.resource.data.id 
    && request.auth.uid == resource.data.id
    && request.auth.uid == userId;
      
    allow delete: if request.auth != null
    && request.auth.uid == resource.data.id
    && request.auth.uid == userId;
}

Here's the duplication part of my react native code:

// Get a reference to the original document
const deleteUser = doc(db, `users/${user?.uid}/`);
const deleteUserDoc = await getDoc(deleteUser);
            
if(!deleteUserDoc.exists()) {
    console.error("User document doesn't exist.");
    return;
}
      
const deleteUserData = deleteUserDoc.data();

// Create a new document reference for the duplicated data 
const dupeUser = doc(firestore, 'users', `Dupe:${user?.uid}/`); // πŸ‘ˆ Causes Rules error
        
// Save the duplicated data
await setDoc(dupeUser, deleteUserData);

Any further help would be greatly appreciated, Thank you!!

Upvotes: 0

Views: 67

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598563

Security is not a yes/no question, so asking an open-ended "what did I miss here" is hard to answer definitively.

That said, here are a few things that jump out:

Enforcing the userId document ID upon creation

You're missing the request.auth.uid == userId check in the create clause. Unless there's a specific reason for not wanting to enforce that check upon creation, I'd recommend:

allow create: if request.auth != null 
&& request.auth.uid == request.resource.data.id
&& request.auth.uid == userId; // πŸ‘ˆ

Don't allow updating the id field in updates

I recommend disallowing updates to the id field, unless you have a requirement to allow transferring ownership of a document (in which case your rules will become a lot more complex).

Based on the simpler case, tht'd be:

allow update: if request.auth != null 
&& request.auth.uid == request.resource.data.id 
&& request.auth.uid == resource.data.id  // πŸ‘ˆ
&& request.auth.uid == userId;

Users should only be able to delete their own document

Right now any user can delete any document, which is a big security risk.

My guess it that you'll want each user to only be able to delete their own document, which'd be:

allow delete: if request.auth != null
&& request.auth.uid == resource.data.id  // πŸ‘ˆ
&& request.auth.uid == userId; // πŸ‘ˆ

Upvotes: 2

Related Questions