Reputation: 2923
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
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:
userId
document ID upon creationYou'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; // π
id
field in updatesI 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;
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