{"id":"CVE-2026-74874","aliases":["EUVD-2026-60093","GHSA-844w-mwfp-wjwf","GHSA-vfgx-5q85-58q3","PYSEC-2026-3754"],"status":"published","title":"openssl_encrypt before 1.4.0 Weak PRNG Steganography Pixel Selection","description":"openssl_encrypt versions before 1.4.0 use Python's non-cryptographic random module for steganographic pixel selection in the generate_pseudorandom_sequence function. Attackers who know the password can recover the Mersenne Twister state from approximately 624 outputs and predict pixel locations containing hidden data for extraction.","severity":{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00437,"percentile":0.38402,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-330","CWE-338"],"published":"2026-03-31T23:43:06Z","modified":"2026-10-28T02:30:57Z","fixes":[{"ecosystem":"PyPI","package":"openssl-encrypt","fixed_in":["1.4.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"openssl-encrypt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.4.0"}]}]},{"source":"osv","ecosystem":"PyPI","package":"openssl-encrypt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.4.0"}]}],"versions":["0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.3.0","0.3.1","0.3.2","0.3.3","0.4.0","0.4.1","0.4.2","0.4.3","0.4.4","0.5.0","0.5.1","0.5.3","0.6.0rc1","0.7.0rc2","0.7.1","0.7.2","0.8.0","0.8.1","0.8.2","0.9.2","1.0.0","1.0.1","1.0.2","1.0.3","1.1.0","1.2.0","1.2.1","1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.4.0b3","1.4.0b4","1.4.0b5","1.4.0b6","1.4.0b7","1.4.0b8"]},{"source":"osv","ecosystem":"PyPI","package":"openssl-encrypt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.4.0"}]}],"versions":["0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.3.0","0.3.1","0.3.2","0.3.3","0.4.0","0.4.1","0.4.2","0.4.3","0.4.4","0.5.0","0.5.1","0.5.3","0.6.0rc1","0.7.0rc2","0.7.1","0.7.2","0.8.0","0.8.1","0.8.2","0.9.2","1.0.0","1.0.1","1.0.2","1.0.3","1.1.0","1.2.0","1.2.1","1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.4.0b3","1.4.0b4","1.4.0b5","1.4.0b6","1.4.0b7","1.4.0b8"]}],"products":[{"vendor":"jahlives","product":"openssl_encrypt"}],"references":[{"url":"https://github.com/jahlives/openssl_encrypt/security/advisories/GHSA-vfgx-5q85-58q3","tags":["vendor-advisory","Mitigation","Vendor Advisory","advisory","web"]},{"url":"https://www.vulncheck.com/advisories/openssl-encrypt-before-weak-prng-steganography-pixel-selection","tags":["third-party-advisory","Third Party Advisory","advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-74874","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-844w-mwfp-wjwf"},{"url":"https://github.com/jahlives/openssl_encrypt/commit/09e96e090417d34d2f533f6810d3cd4f77810101","tags":["web"]},{"url":"https://github.com/advisories/GHSA-vfgx-5q85-58q3"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/74xxx/CVE-2026-74874.json","tags":["advisory"]},{"url":"https://github.com/jahlives/openssl_encrypt","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-74874","title":"openssl_encrypt before 1.4.0 Weak PRNG Steganography Pixel Selection","description":"openssl_encrypt versions before 1.4.0 use Python's non-cryptographic random module for steganographic pixel selection in the generate_pseudorandom_sequence function. Attackers who know the password can recover the Mersenne Twister state from approximately 624 outputs and predict pixel locations containing hidden data for extraction.","status":"published","published":"2026-08-17T11:04:42.912Z","modified":"2026-10-08T15:24:48.734Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high","assessor":"cna"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"high","assessor":"cna"}],"cwes":["CWE-338"],"updated_at":"2026-11-02T14:20:03.081354Z"}],"euvd":[{"id":"EUVD-2026-60093","description":"openssl_encrypt versions before 1.4.0 use Python's non-cryptographic random module for steganographic pixel selection in the generate_pseudorandom_sequence function. Attackers who know the password can recover the Mersenne Twister state from approximately 624 outputs and predict pixel locations containing hidden data for extraction.","status":"published","published":"2026-08-17T11:04:42Z","modified":"2026-10-08T15:24:48Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T17:27:31.218078Z"}],"ghsa":[{"id":"GHSA-844w-mwfp-wjwf","title":"openssl_encrypt versions before 1.4.0 use Python's non-cryptographic random module for...","description":"openssl_encrypt versions before 1.4.0 use Python's non-cryptographic random module for steganographic pixel selection in the generate_pseudorandom_sequence function. Attackers who know the password can recover the Mersenne Twister state from approximately 624 outputs and predict pixel locations containing hidden data for extraction.","status":"published","published":"2026-08-17T12:32:22Z","modified":"2026-08-17T12:32:23Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/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","level":"high"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"high"}],"cwes":["CWE-338"],"updated_at":"2026-11-02T15:10:34.0369Z"},{"id":"GHSA-vfgx-5q85-58q3","title":"openssl-encrypt has non-cryptographic PRNG used for steganography pixel selection","description":"### Summary\n\nThe `generate_pseudorandom_sequence()` function in `openssl_encrypt/plugins/steganography/core/utils.py` at **lines 89-91** uses Python's `random` module (Mersenne Twister) for steganographic pixel/sample selection.\n\n### Affected Code\n\n```python\nrandom.seed(seed)\nsequence = random.sample(range(max_value), min(length, max_value))\nreturn sequence\n```\n\nAdditionally, the steganography password is stored as a plain Python string (not `SecureBytes`) and only 8 bytes (64 bits) of the SHA-256 hash are used for the seed, reducing effective security to 64 bits.\n\n### Impact\n\nThe Mersenne Twister's state can be recovered from approximately 624 outputs. An attacker who knows or guesses the password can predict the PRNG sequence and determine exactly which pixels contain hidden data, potentially extracting the hidden data without the password.\n\n### Recommended Fix\n\n- Use HMAC-DRBG or `secrets` module for cryptographically secure pixel selection\n- Use full 32-byte SHA-256 output as seed material\n- Store the password in `SecureBytes` instead of a plain string\n\n### Fix\n\nFixed in commit `09e96e0` on branch `releases/1.4.x` — replaced random.seed(hash(password)) with HMAC-SHA256 based CSPRNG (Fisher-Yates shuffle) and numpy Generator with HMAC-derived seeds across all steganography format modules.","status":"published","published":"2026-03-31T23:43:06Z","modified":"2026-03-31T23:43:07Z","cvss":[{"version":"4.0","score":6.6,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:U","level":"medium"}],"cwes":["CWE-330"],"updated_at":"2026-11-02T14:39:47.075804Z"}],"nvd":[{"id":"CVE-2026-74874","description":"openssl_encrypt versions before 1.4.0 use Python's non-cryptographic random module for steganographic pixel selection in the generate_pseudorandom_sequence function. Attackers who know the password can recover the Mersenne Twister state from approximately 624 outputs and predict pixel locations containing hidden data for extraction.","status":"published","published":"2026-08-17T11:16:41.813Z","modified":"2026-10-08T16:17:39.117Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/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","level":"high","assessor":"secondary"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"high","assessor":"secondary"}],"cwes":["CWE-338"],"updated_at":"2026-11-02T14:12:38.647684Z"}],"osv":[{"id":"CVE-2026-74874","title":"openssl_encrypt before 1.4.0 Weak PRNG Steganography Pixel Selection","description":"openssl_encrypt versions before 1.4.0 use Python's non-cryptographic random module for steganographic pixel selection in the generate_pseudorandom_sequence function. Attackers who know the password can recover the Mersenne Twister state from approximately 624 outputs and predict pixel locations containing hidden data for extraction.","status":"published","published":"2026-08-17T11:04:42.912Z","modified":"2026-10-28T02:30:57.098373175Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-338"],"updated_at":"2026-11-02T15:45:16.748692Z"},{"id":"GHSA-vfgx-5q85-58q3","title":"openssl-encrypt has non-cryptographic PRNG used for steganography pixel selection","description":"### Summary\n\nThe `generate_pseudorandom_sequence()` function in `openssl_encrypt/plugins/steganography/core/utils.py` at **lines 89-91** uses Python's `random` module (Mersenne Twister) for steganographic pixel/sample selection.\n\n### Affected Code\n\n```python\nrandom.seed(seed)\nsequence = random.sample(range(max_value), min(length, max_value))\nreturn sequence\n```\n\nAdditionally, the steganography password is stored as a plain Python string (not `SecureBytes`) and only 8 bytes (64 bits) of the SHA-256 hash are used for the seed, reducing effective security to 64 bits.\n\n### Impact\n\nThe Mersenne Twister's state can be recovered from approximately 624 outputs. An attacker who knows or guesses the password can predict the PRNG sequence and determine exactly which pixels contain hidden data, potentially extracting the hidden data without the password.\n\n### Recommended Fix\n\n- Use HMAC-DRBG or `secrets` module for cryptographically secure pixel selection\n- Use full 32-byte SHA-256 output as seed material\n- Store the password in `SecureBytes` instead of a plain string\n\n### Fix\n\nFixed in commit `09e96e0` on branch `releases/1.4.x` — replaced random.seed(hash(password)) with HMAC-SHA256 based CSPRNG (Fisher-Yates shuffle) and numpy Generator with HMAC-derived seeds across all steganography format modules.","status":"published","published":"2026-03-31T23:43:06Z","modified":"2026-09-02T09:10:33.726280398Z","cvss":[{"version":"4.0","score":6.6,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:U","level":"medium"}],"cwes":["CWE-330"],"updated_at":"2026-11-02T15:46:57.348035Z"},{"id":"PYSEC-2026-3754","description":"openssl_encrypt versions before 1.4.0 use Python's non-cryptographic random module for steganographic pixel selection in the generate_pseudorandom_sequence function. Attackers who know the password can recover the Mersenne Twister state from approximately 624 outputs and predict pixel locations containing hidden data for extraction.","status":"published","published":"2026-08-17T11:16:41.813Z","modified":"2026-09-02T09:00:04.184109412Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/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","level":"high"}],"updated_at":"2026-11-02T15:52:57.255153Z"}]}}
