From debefb8898a9f7839e0bb27a7b4de1e32cec47b6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 09:10:26 +0000 Subject: [PATCH] Fix weak random number generation Co-authored-by: thirdeyenation <133812267+thirdeyenation@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ agent.py | 4 ++-- helpers/guids.py | 4 ++-- prepare.py | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000000..2a948800c3 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-06-25 - Weak random number generation +**Vulnerability:** Weak random number generation using `random.choices` for generating passwords and internal identifiers. +**Learning:** `random.choices` is a pseudo-random number generator that is not cryptographically secure, and should not be used in security-sensitive contexts like generating passwords. +**Prevention:** Use `secrets.choice` or `secrets.token_urlsafe` for generating random strings or passwords. diff --git a/agent.py b/agent.py index 267a908077..f29f0d41da 100644 --- a/agent.py +++ b/agent.py @@ -1,4 +1,4 @@ -import asyncio, random, string, threading +import asyncio, random, string, threading, secrets from collections import OrderedDict from dataclasses import dataclass, field @@ -135,7 +135,7 @@ def all(): @staticmethod def generate_id(): def generate_short_id(): - return "".join(random.choices(string.ascii_letters + string.digits, k=8)) + return "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(8)) while True: short_id = generate_short_id() diff --git a/helpers/guids.py b/helpers/guids.py index f0def4b4c6..41439e4bbe 100644 --- a/helpers/guids.py +++ b/helpers/guids.py @@ -1,4 +1,4 @@ -import random, string +import random, string, secrets def generate_id(length: int = 8) -> str: - return "".join(random.choices(string.ascii_letters + string.digits, k=length)) + return "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(length)) diff --git a/prepare.py b/prepare.py index a4c4af9c45..ec0fcc714d 100644 --- a/prepare.py +++ b/prepare.py @@ -1,6 +1,7 @@ from helpers import dotenv, runtime, settings import string import random +import secrets import sys from helpers.print_style import PrintStyle @@ -33,7 +34,7 @@ def _retire_legacy_collabora_runtime() -> None: # generate random root password if not set (for SSH) root_pass = dotenv.get_dotenv_value(dotenv.KEY_ROOT_PASSWORD) if not root_pass: - root_pass = "".join(random.choices(string.ascii_letters + string.digits, k=32)) + root_pass = "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(32)) PrintStyle.standard("Changing root password...") settings.set_root_password(root_pass)