From 8de7ecc17db71b075b6415abbe1b9cfd5d52f9f6 Mon Sep 17 00:00:00 2001 From: Peter Robicheaux Date: Wed, 4 Feb 2026 20:50:20 -0800 Subject: [PATCH] fix: use cryptographically secure random for new document ids --- google/cloud/firestore_v1/base_collection.py | 8 ++++++-- tests/unit/v1/test_base_collection.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/google/cloud/firestore_v1/base_collection.py b/google/cloud/firestore_v1/base_collection.py index 25d07aec9..8793def41 100644 --- a/google/cloud/firestore_v1/base_collection.py +++ b/google/cloud/firestore_v1/base_collection.py @@ -60,6 +60,7 @@ import datetime _AUTO_ID_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" +system_random = random.SystemRandom() class BaseCollectionReference(Generic[QueryType]): @@ -623,8 +624,11 @@ def _auto_id() -> str: str: A 20 character string composed of digits, uppercase and lowercase and letters. """ - - return "".join(random.choice(_AUTO_ID_CHARS) for _ in range(20)) + try: + return "".join(system_random.choice(_AUTO_ID_CHARS) for _ in range(20)) + # Very old Unix systems don't have os.urandom (/dev/urandom), in which case use random.choice + except NotImplementedError: + return "".join(random.choice(_AUTO_ID_CHARS) for _ in range(20)) def _item_to_document_ref(collection_reference, item): diff --git a/tests/unit/v1/test_base_collection.py b/tests/unit/v1/test_base_collection.py index 9124e4d01..e2c2dcdf2 100644 --- a/tests/unit/v1/test_base_collection.py +++ b/tests/unit/v1/test_base_collection.py @@ -437,7 +437,7 @@ def test_basecollectionreference_pipeline(mock_query): assert pipeline == mock_query._build_pipeline.return_value -@mock.patch("random.choice") +@mock.patch("random.SystemRandom.choice") def test__auto_id(mock_rand_choice): from google.cloud.firestore_v1.base_collection import _AUTO_ID_CHARS, _auto_id