From 6d428ca8f027c78aff320589430fe56401e0889a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Sj=C3=B6gren?= Date: Thu, 20 Nov 2025 18:32:32 +0100 Subject: [PATCH] replace random with secrets when generating passwords (#85971) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --------- Signed-off-by: Thomas Sjögren Co-authored-by: Felix Fontein --- changelogs/fragments/replace-random-with-secrets.yml | 3 +++ lib/ansible/plugins/lookup/password.py | 4 ++-- lib/ansible/utils/encrypt.py | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/replace-random-with-secrets.yml diff --git a/changelogs/fragments/replace-random-with-secrets.yml b/changelogs/fragments/replace-random-with-secrets.yml new file mode 100644 index 00000000000..f09f5796268 --- /dev/null +++ b/changelogs/fragments/replace-random-with-secrets.yml @@ -0,0 +1,3 @@ +bugfixes: + - password lookup plugin - replace random.SystemRandom() with secrets.SystemRandom() when + generating passwords (https://github.com/ansible/ansible/issues/85956, https://github.com/ansible/ansible/pull/85971). diff --git a/lib/ansible/plugins/lookup/password.py b/lib/ansible/plugins/lookup/password.py index a0718fbf18f..86e17300719 100644 --- a/lib/ansible/plugins/lookup/password.py +++ b/lib/ansible/plugins/lookup/password.py @@ -67,7 +67,7 @@ DOCUMENTATION = """ description: - A seed to initialize the random number generator. - Identical seeds will yield identical passwords. - - Use this for random-but-idempotent password generation. + - B(Note) that a weak seed, one without enough entropy, will not create a sufficiently secure encryption for the password. type: str notes: - A great alternative to the password lookup plugin, @@ -113,7 +113,7 @@ EXAMPLES = """ ansible.builtin.set_fact: random_pod_name: "web-{{ lookup('ansible.builtin.password', '/dev/null', chars=['ascii_lowercase', 'digits'], length=8) }}" -- name: create random but idempotent password +- name: create idempotent password for use in testing/CI, not recommended for production ansible.builtin.set_fact: password: "{{ lookup('ansible.builtin.password', '/dev/null', seed=inventory_hostname) }}" """ diff --git a/lib/ansible/utils/encrypt.py b/lib/ansible/utils/encrypt.py index 68df755f0c5..5043348e824 100644 --- a/lib/ansible/utils/encrypt.py +++ b/lib/ansible/utils/encrypt.py @@ -63,9 +63,10 @@ def random_password(length=DEFAULT_PASSWORD_LENGTH, chars=C.DEFAULT_PASSWORD_CHA raise AnsibleAssertionError(f'{chars=!r} ({type(chars)}) is not a {type(str)}.') if seed is None: - random_generator = random.SystemRandom() + random_generator = secrets.SystemRandom() else: random_generator = random.Random(seed) + return u''.join(random_generator.choice(chars) for dummy in range(length))