firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.82k stars 884 forks source link

[Feature Request] Include document path in permissions errors #7160

Open samatcolumn opened 1 year ago

samatcolumn commented 1 year ago

[REQUIRED] Describe your environment

[REQUIRED] Describe the problem

Steps to reproduce:

This is a feature request, so apologies for abusing the template. It would be incredibly helpful if the "Missing or insufficient permissions." error thrown by the Firestore SDK had some information on what request failed. I realize for queries this might be difficult but for simple document CRUD operations, it would be great if the error object included the document path.

Firestore is incredibly reliable so most developers are not in the habit of adding try/catch around most simple operations. This means when you do get an accidental error like a rules failure, it may not be caught locally and when you see the error in your app metrics it may be lacking all context. So I'd love for the Firestore SDK to help me carry that context.

dconeybe commented 1 year ago

Sounds like a reasonable request, especially for single-document queries. Collection and collection-group queries can probably also include the information about the collection and/or collection-group as well. I'll take a look into it, but can't promise an ETA. If all goes well, I'd hope to have this change in the next release or two.

samatcolumn commented 1 year ago

@dconeybe wow that would be amazing. I was definitely expecting such a basic request to be met with "here's the very good reason why we can't do and haven't done that" haha.

dconeybe commented 1 year ago

Update: I haven't started working on this yet. I'm looking into whether including document paths in error messages has any PII concerns. Unfortunately, this isn't a high priority relative to other things we are working on so it will take some time to get this released, more than I had originally hoped. I'll post back when I have updates.

LanderBeeuwsaert commented 1 year ago

FYI, you can create the functionality yourself (we're using angularFire here, but same should be possible without): connectToDocsFromQuery$(query: Query): Observable<T[]> { return collectionSnapshots(query).pipe( catchError(e => { // if it's a missing permissions error, we want to have more detailed information if (e.message === 'Missing or insufficient permissions.') { e.message = Missing or insufficient permissions: ${this.stringifyQuery(query)}; } // permissions error in emulator if (e.message.startsWith(\nfalse for ')) { e.message += : ${this.stringifyQuery(query)}; } throw e; }), ); }

connectToDoc$(path: string, patcherList?: PatcherList, addMetaData: boolean = true): Observable { const docReference = this.docRef(path);

return docData(docReference).pipe(
  map(localDoc => (localDoc: localDoc) as T),
  catchError(e => {
    // if it's a missing permissions error, we want to have more detailed information
    if (e.message === 'Missing or insufficient permissions.') {
      e.message = `Missing or insufficient permissions: ${path}`;
    }
    // permissions error in emulator
    if (e.message.startsWith(`\nfalse for '`)) {
      e.message += `: ${path}`;
    }
    throw e;
  }),
);

}

samatcolumn commented 1 year ago

@dconeybe just bumping this one in case it has any chance of getting a little higher on the priority list.

dconeybe commented 1 year ago

Yep, this issue is still on my radar. I don't have any timeline guidance though.

ALiangLiang commented 1 year ago

It's good for us for tracing which query caused the error. We use Sentry to catch global error and the FirestoreError's property "stack" same as message which is always be "FirebaseError: Missing or insufficient permissions." so we cannot debug.

image image

cybercoder-naj commented 7 months ago

Bump!!

My team and I used Firebase for our most recent project and we had a great experience with it. However initially, we had lenient Firebase rules; and we found out that some users gave themselves an auth account and a ticket to join our event!

When we made our rules stricter but faced multiple Missing or insufficient permissions during further development. Some rules had about 3-4 conditions in disjunction. Since there was no other information tied to this, every debug took more than necessary time to fix.

Is it possible to have a flag/options passed to initialiseApp that shows the exact log as to why permissions failed? The best possible log would look something like:

allow write: isAdmin() || (isParticipant() && userDocExists(request.auth.uid))
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                            This clause is false
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                           Hence, this clause is false

Of course, I am not entirely sure what the architecture of Firebase looks like or if this feature could be implemented. But any kind of logs from the request would be appreciated to help ease writing the firebase rules.

dconeybe commented 7 months ago

@cybercoder-naj Unfortunately, the Firestore SDK will never be given details about security rules violations from the backend. That information would be too useful to would-be malicious users trying to defeat the rules.

However, there are some useful tools at your diposal for debugging security rules, which sound like they could have expedited your debugging. This video showcases them: https://www.youtube.com/watch?v=TglPc74M3DM&t=513s

Unit Testing Security Rules

If you don't have them set up, it's a good idea to write unit tests for your security rules to ensure that they do, indeed, allow only the desired requests. These tests can also help understand the restrictions that the rules are enforcing. The tests are written in JavaScript or TypeScript using the @firebase/rules-unit-testing library. Details can be found here: https://firebase.google.com/docs/firestore/security/test-rules-emulator

Security Rules in the Firestore Emulator

The Firestore emulator has a web console that shows details about how security rules are evaluated on every request. In fact, it shows the details about each expression and how it evaluates, exactly like you have requested. It even supports surrounding an expression with debug(...) so that the expression's result is included in the Firestore emulator's logs. These features are shown in the video link above.

I hope this helps.