-
Notifications
You must be signed in to change notification settings - Fork 81
Add firestore path validation examples #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -409,6 +409,33 @@ within the context. | |||||||||||||||||||||||||||
| allow create: if isScopedPath(request.resource.data.imageBucket) && ... | ||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| When validating a field that contains a document ID that will be interpolated | ||||||||||||||||||||||||||||
| into a path, you **MUST** validate that it is a non-empty single path segment. | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| **Example:** | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| ```javascript | ||||||||||||||||||||||||||||
| function isValidPostId(postId) { | ||||||||||||||||||||||||||||
| return postId is string && | ||||||||||||||||||||||||||||
| postId.matches('^[^/]+$') && | ||||||||||||||||||||||||||||
| exists(/databases/$(database)/documents/posts/$(postId)); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| When validating a field that contains a `DocumentReference`, you **MUST** check | ||||||||||||||||||||||||||||
| that it exactly matches the expected path. | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| **Example:** | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| ```javascript | ||||||||||||||||||||||||||||
| function isValidPostReference(postRef) { | ||||||||||||||||||||||||||||
| return postRef is path && | ||||||||||||||||||||||||||||
| postRef == | ||||||||||||||||||||||||||||
| /databases/$(database)/documents/posts/$(postRef[4]) && | ||||||||||||||||||||||||||||
| exists(postRef); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
Comment on lines
+431
to
+436
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Accessing path segments by index (e.g.,
Suggested change
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| #### 4. Secure Counter Updates | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| When allowing users to update a counter (like `voteCount` or `answerCount`), you | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -409,6 +409,33 @@ within the context. | |||||||||||||||||||||||||||
| allow create: if isScopedPath(request.resource.data.imageBucket) && ... | ||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| When validating a field that contains a document ID that will be interpolated | ||||||||||||||||||||||||||||
| into a path, you **MUST** validate that it is a non-empty single path segment. | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| **Example:** | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| ```javascript | ||||||||||||||||||||||||||||
| function isValidPostId(postId) { | ||||||||||||||||||||||||||||
| return postId is string && | ||||||||||||||||||||||||||||
| postId.matches('^[^/]+$') && | ||||||||||||||||||||||||||||
| exists(/databases/$(database)/documents/posts/$(postId)); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
Comment on lines
+418
to
+422
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To prevent potential resource exhaustion or DoS attacks via extremely large document IDs, it is highly recommended to enforce a realistic size limit on the
Suggested change
|
||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| When validating a field that contains a `DocumentReference`, you **MUST** check | ||||||||||||||||||||||||||||
| that it exactly matches the expected path. | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| **Example:** | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| ```javascript | ||||||||||||||||||||||||||||
| function isValidPostReference(postRef) { | ||||||||||||||||||||||||||||
| return postRef is path && | ||||||||||||||||||||||||||||
| postRef == | ||||||||||||||||||||||||||||
| /databases/$(database)/documents/posts/$(postRef[4]) && | ||||||||||||||||||||||||||||
| exists(postRef); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
Comment on lines
+431
to
+436
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Accessing path segments by index (e.g.,
Suggested change
|
||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| #### 4. Secure Counter Updates | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| When allowing users to update a counter (like `voteCount` or `answerCount`), you | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To prevent potential resource exhaustion or DoS attacks via extremely large document IDs, it is highly recommended to enforce a realistic size limit on the
postIdstring (e.g.,postId.size() < 100), as outlined in the security guidelines of this document.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this example, we have already confirmed that the relevant document exists, so there should be no need to impose a length restriction on the ID.
Also, document IDs already have a maximum length limit. If the intention is to validate the document ID accurately, various additional requirements would need to be checked, as shown below:
https://firebase.google.com/docs/firestore/quotas#collections_documents_and_fields