SECURITY: enforce profile ownership and immutable identity fields
This commit is contained in:
parent
00c86067cc
commit
50330f6867
|
|
@ -9,10 +9,33 @@ service cloud.firestore {
|
|||
return signedIn() && request.auth.uid == userId;
|
||||
}
|
||||
|
||||
// Every user-owned document is isolated by the Firebase UID. Cloudflare R2
|
||||
// is protected separately by the Worker using the same Firebase ID token.
|
||||
function validUserCreate(userId) {
|
||||
return ownsUser(userId)
|
||||
&& request.resource.data.id == userId
|
||||
&& request.resource.data.keys().hasOnly([
|
||||
'id', 'username', 'displayName', 'profilePhotoUrl', 'bio',
|
||||
'location', 'createdAt', 'updatedAt', 'privacySettings', 'preferences'
|
||||
]);
|
||||
}
|
||||
|
||||
function validUserUpdate(userId) {
|
||||
return ownsUser(userId)
|
||||
&& request.resource.data.id == resource.data.id
|
||||
&& request.resource.data.createdAt == resource.data.createdAt
|
||||
&& request.resource.data.keys().hasOnly([
|
||||
'id', 'username', 'displayName', 'profilePhotoUrl', 'bio',
|
||||
'location', 'createdAt', 'updatedAt', 'privacySettings', 'preferences'
|
||||
]);
|
||||
}
|
||||
|
||||
// Firebase UID is the security boundary. Profile fields are explicitly
|
||||
// allow-listed so clients cannot turn the account document into a secret
|
||||
// or entitlement store.
|
||||
match /users/{userId} {
|
||||
allow read, write: if ownsUser(userId);
|
||||
allow create: if validUserCreate(userId);
|
||||
allow read: if ownsUser(userId);
|
||||
allow update: if validUserUpdate(userId);
|
||||
allow delete: if ownsUser(userId);
|
||||
|
||||
match /rides/{rideId} {
|
||||
allow read, write: if ownsUser(userId);
|
||||
|
|
@ -25,7 +48,8 @@ service cloud.firestore {
|
|||
}
|
||||
|
||||
match /motorcycles/{motorcycleId} {
|
||||
allow read, write: if ownsUser(userId);
|
||||
allow read, write: if ownsUser(userId)
|
||||
&& request.resource.data.ownerId == userId;
|
||||
}
|
||||
|
||||
match /trips/{tripId} {
|
||||
|
|
@ -41,8 +65,8 @@ service cloud.firestore {
|
|||
}
|
||||
}
|
||||
|
||||
// Future public/group collections must be added with explicit field-level
|
||||
// authorization. Do not use a global recursive wildcard here.
|
||||
// Future collaborative resources must get explicit membership/field-level
|
||||
// authorization before they are exposed.
|
||||
match /groupRides/{groupRideId} {
|
||||
allow read, write: if false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue