Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions skills/firebase-firestore/references/enterprise/security_rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

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;
}

```

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

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.

```

#### 4. Secure Counter Updates

When allowing users to update a counter (like `voteCount` or `answerCount`), you
Expand Down
27 changes: 27 additions & 0 deletions skills/firebase-firestore/references/standard/security_rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

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));
}

```

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

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);
}

```

#### 4. Secure Counter Updates

When allowing users to update a counter (like `voteCount` or `answerCount`), you
Expand Down