Skip to content

Add firestore path validation examples - #165

Open
ishowta wants to merge 1 commit into
firebase:mainfrom
ishowta:feature/add-firestore-path-validation-examples
Open

Add firestore path validation examples#165
ishowta wants to merge 1 commit into
firebase:mainfrom
ishowta:feature/add-firestore-path-validation-examples

Conversation

@ishowta

@ishowta ishowta commented Aug 8, 2026

Copy link
Copy Markdown

This PR adds document ID and DocumentReference validation examples to the Strict Path and Relationship Scoping section of the Firestore security rules guidance for both Standard and Enterprise editions.

The examples demonstrate how to prevent path substitution by validating document IDs as single path segments and ensuring DocumentReference fields exactly match the expected path.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds guidelines and examples for validating document IDs and DocumentReference fields in Firestore security rules within both the enterprise and standard reference documentation. The review feedback suggests two key improvements to the provided code examples: enforcing a size limit on document IDs to prevent potential resource exhaustion or DoS attacks, and validating path sizes before accessing specific segments by index to avoid out-of-bounds runtime evaluation errors. All comments are constructive and provide actionable code suggestions.

Comment on lines +418 to +422
function isValidPostId(postId) {
return postId is string &&
postId.matches('^[^/]+$') &&
exists(/databases/$(database)/documents/posts/$(postId));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

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 postId string (e.g., postId.size() < 100), as outlined in the security guidelines of this document.

Suggested change
function isValidPostId(postId) {
return postId is string &&
postId.matches('^[^/]+$') &&
exists(/databases/$(database)/documents/posts/$(postId));
}
function isValidPostId(postId) {
return postId is string &&
postId.size() > 0 &&
postId.size() < 100 &&
postId.matches('^[^/]+$') &&
exists(/databases/$(database)/documents/posts/$(postId));
}

Copy link
Copy Markdown
Author

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

function validateID(val){
  return val is string &&
  val != "" &&
  val.toUtf8().size() <= 1500 &&
  val.matches('^[^/]*$') &&
  val != "." &&
  val != ".." &&
  val.matches('^__.*__$') == false;
}

Comment on lines +431 to +436
function isValidPostReference(postRef) {
return postRef is path &&
postRef ==
/databases/$(database)/documents/posts/$(postRef[4]) &&
exists(postRef);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Accessing path segments by index (e.g., postRef[4]) can throw an out-of-bounds runtime evaluation error if the path has fewer segments than expected. To ensure robustness and prevent unexpected evaluation failures, validate the path size (e.g., postRef.size() == 5) before accessing specific segments.

Suggested change
function isValidPostReference(postRef) {
return postRef is path &&
postRef ==
/databases/$(database)/documents/posts/$(postRef[4]) &&
exists(postRef);
}
function isValidPostReference(postRef) {
return postRef is path &&
postRef.size() == 5 &&
postRef ==
/databases/$(database)/documents/posts/$(postRef[4]) &&
exists(postRef);
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path.size() is not available. If this still needs to be done, something like string(path).split("/").size() may be necessary.

Comment on lines +418 to +422
function isValidPostId(postId) {
return postId is string &&
postId.matches('^[^/]+$') &&
exists(/databases/$(database)/documents/posts/$(postId));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

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 postId string (e.g., postId.size() < 100), as outlined in the security guidelines of this document.

Suggested change
function isValidPostId(postId) {
return postId is string &&
postId.matches('^[^/]+$') &&
exists(/databases/$(database)/documents/posts/$(postId));
}
function isValidPostId(postId) {
return postId is string &&
postId.size() > 0 &&
postId.size() < 100 &&
postId.matches('^[^/]+$') &&
exists(/databases/$(database)/documents/posts/$(postId));
}

Comment on lines +431 to +436
function isValidPostReference(postRef) {
return postRef is path &&
postRef ==
/databases/$(database)/documents/posts/$(postRef[4]) &&
exists(postRef);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Accessing path segments by index (e.g., postRef[4]) can throw an out-of-bounds runtime evaluation error if the path has fewer segments than expected. To ensure robustness and prevent unexpected evaluation failures, validate the path size (e.g., postRef.size() == 5) before accessing specific segments.

Suggested change
function isValidPostReference(postRef) {
return postRef is path &&
postRef ==
/databases/$(database)/documents/posts/$(postRef[4]) &&
exists(postRef);
}
function isValidPostReference(postRef) {
return postRef is path &&
postRef.size() == 5 &&
postRef ==
/databases/$(database)/documents/posts/$(postRef[4]) &&
exists(postRef);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant