I have this structure in firestore
I need to limit access to data where expirationTimestamp > now
I have found this example
match /collection/{document} {
allow read: if request.time < resource.data.expirationTimestamp;
}
but I always get "Simulated data access denied"
anyone know why? Thanks
request.time is known not to work in the Firestore console simulator. Any reference to request.time immediately (and incorrectly) rejects access in the simulator. It should work fine for fully published rules.
Related
Below is a sample security code I am trying to implement in production but it keeps throwing following error.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if request.time < timestamp.date(2022, 4, 13);
}
}
}
Error:
Missing or insufficient permissions.
I only want a "read only" database for production. What am I missing here?
allow read: if request.time < timestamp.date(2022, 4, 13);
This statement returns true only when time of current time is before 13th April 2022 that was yesterday.
match /{doc=**} {
allow read: if true;
}
You can switch to rules shown above to always allow read operations.
However, these rules allow anyone on the internet to read your database (that should be fine for this specific use case) but you should write secure rules if you also have any other use case.
Checkout more about security rules in the documentation. Also checkout Get to know Cloud Firestore | Security Rules video on Firebase's Youtube channel.
if you want a read-only database then you're probably looking for the ruleset something like this:
allow read;
allow write: if false;
And, just an extra tip, give your users the most minimal permissions. That means, in this case, itself, you probably don't want to give your users read permission to the entire database.
So, it's always a better choice to allow reading or writing only to the specific collections or documents.
I'm quite new to Firebase, but either I misunderstand something completely or there's something wrong with my Firebase account.
I added a Firestore Database to my Firebase app, and initially I chose it to be created in test mode. As far as I've read in the docs, test mode differs from production mode only by the default security rules.
I wanted to configure my rules properly, so the users can only access their own data.
However, I couldn't make it work, so I tried to configure my Firestore security rules to not allow any read or write operations to anyone. This is what I have currently set in Firestore Database -> Rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
As I understand, these rules should not allow any read or writes in any collection in my database.
The rules playground tells me exactly that when I try to run any request:
However, from my NextJS app I'm still able to get the data as follows:
import {
getFirebaseAdmin
} from 'next-firebase-auth';
// ...
const categoriesDocument = await getFirebaseAdmin()
.firestore()
.collection('categories')
.doc('D47pV7TxNpDNYNkHgfU0')
.get();
and it all works just fine. I'm also sure the data is fetched from exactly this Firestore db, because when I alter some documents it's reflected in the data fetched.
I also noticed that in Firebase in Firestore Database -> Rules -> Monitor rules I see no results at all (total allows: 0, total denies: 0, total errors: 0).
Any idea what could be wrong here? What am I missing?
On the server, you're using firestore as admin. Rules don't apply there.
I am new to firebase and i have an error in console that i really don't know its source:
redux-firestore listener error: FirebaseError: Missing or insufficient permissions.
I don't know is this sufficient to explain my problem, but because i am new to firebase and firestore i can't explain more or bring some piece of code, everything was working fine but suddenly i got this error, what can be the source of that error?? how to fix it??
One reason you can suddenly be denied access to your Firebase database without having changed anything is that database access rules can have expiry dates, and the default Open Access rules do. E.g., if you examine your database rules at https://console.firebase.google.com/, you may see a line similar to this:
match /{document=**} {
allow read, write: if request.time < timestamp.date(2020, 7, 4);
}
Try changing the date into the future (and click Publish), and see if that helps.
Note: You should set up proper rules that do not expire ASAP (unless expiry is part of your design). See Avoid insecure rules for more details.
For our app we need to be able to offer groups access to files. Each user can have a large number of groups so it does not make sense to use the "custom token" solution (which is anyways very awkward.
As I discovered, Firebase is very limited with its Storage security rules. The main issue is that we keep Group definitions in Firestore which the Storage security rules do not have access to.
To overcome this we decided to include in the metadata of each uploaded file a "token" which anyone in the group has access to. When they download a file, they need to provide this token in the request params (e.g. /groups/xxx/filename.jpg?token=abc).
So I went ahead and wrote these rules:
match /groups/{groupId}/{filename} {
allow read: if request.auth != null && request.params.token == resource.metadata.token;
allow write: if request.auth.uid == userId
&& request.resource.size < 1 * 1024 * 1024
&& request.resource.contentType.matches('image/.*')
&& (resource == null || request.resource.contentType == resource.contentType)
&& imageId.size() < 32
;
}
But when I run it in the simulator I get the error: "Error: simulator.rules line [23], column [43]. Property params is undefined on object." which points to the rule with "request.params.token"
The documentation specifically states that we have access to the params object from the request object: https://firebase.google.com/docs/storage/security/secure-files?authuser=0#request_evaluation
Due to the severe limitations of Firebase being able to query Firestore data in Storage and the incorrect documentation regarding request.param not being available, we had to use a different approach.
We decided to use the following URL when querying files of a group:
/groups/{groupId}/{token}/{filename}
The only security requirement is for the user to be logged in. Since the above token is a secret and only available to group members, we find it to be pretty secure. We do not allow listing of directories so it is not possible to simply list the /groups/{groupId} to find any tokens.
Note: another optimization could be to not include the {groupId} in the path but we felt it was better to include for debug and management purposes.
If anyone feels this is an insecure way, please let us know on the comments!
Thanks!
It sounds like you're trying to proxy some data from Cloud Firestore into a Cloud Storage request for use in security rules. This is currently not feasible. (On top of that request.params currently refers to APIs that aren't documented, so it can't really be used. I've brought this up with the team, and we feel request.params should likely be removed from security rules docs.)
If you want to assign a Firebase Auth user some group identity that can be verified across products (Firestore, Storage, and Realtime Database), you can use custom claims for this. It will require some work on your backend to assign, directly to the user account, the value(s) you want to check. If you do it correctly, the values you set in that JSON blob will show up in request.auth.token in both Firestore and Storage security rules.
I'm trying to get request.auth.uid == userId to be tested but I'm getting 'Simulated read denied'.
I checked all of the basic questions before inputting this issue -
Did you deploy security rules?
I deployed the rules via the fireconsole (clicking the publish button and waiting for a min).
Did you have loggedin using Firebase Authentication?
I haven't implemented this work, I'm trying to test the security rules via using simulator in console.
I tried basic rule below and it works fine.
if request.auth.uid != null;
Here are the screenshots of my testing -
When using the security rules simulator, you need to enter the exact, full path of the document to read. You can't use wildcards. Right now, you're trying to using a wildcard in the document path: "/users/{userId}" This isn't going to work. This makes the userId variable in your rules become literally the string "{userId}". What you need to do instead is paste the actual ID of the document you want to test for reading into the form. This is going to be the UID starting with "JoF".
BTW: You are not required to deploy rules in order to test them in the simulator. You can choose to deploy them only after you've tested them.