{"id":"GHSA-73g8-5h73-26h4","revision":null,"records":[{"revision":"0c60a09cf27d405790bf69a9d0e201fe","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2025-64767","aliases":[],"title":"hpke-js reuses AEAD nonces","description":"hpke-js is a Hybrid Public Key Encryption (HPKE) module built on top of Web Cryptography API. Prior to version 1.7.5, the public SenderContext Seal() API has a race condition which allows for the same AEAD nonce to be re-used for multiple Seal() calls. This can lead to complete loss of Confidentiality and Integrity of the produced messages. This issue has been patched in version 1.7.5.","state":0,"publishedAt":"2025-11-21T18:47:19.93+00:00","modifiedAt":"2025-11-21T19:01:11.833+00:00","affected":[{"ecosystem":"Vendor product","name":"hpke-js","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"dajiaji\",\n                    \"product\": \"hpke-js\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 1.7.5\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":"CRITICAL"}],"references":["https://github.com/dajiaji/hpke-js/security/advisories/GHSA-73g8-5h73-26h4","https://github.com/dajiaji/hpke-js/commit/94a767c9b9f37ce48d5cd86f7017d8cacd294aaf","https://github.com/dajiaji/hpke-js/blob/b7fd3592c7c08660c98289d67c6bb7f891af75c4/packages/core/src/senderContext.ts#L22-L34"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2025-64767","license":"CVE Program Terms of Use","key":"cve-program:CVE-2025-64767","identifiers":["CVE-2025-64767"]},"retained":false,"historicalAffected":[]},{"revision":"b6aa5d59ad034c3caf4e7904f969f1c8","observedAt":"2026-11-09T04:07:52.467+00:00","statement":{"source":"euvd","id":"EUVD-2025-198319","aliases":["CVE-2025-64767","GHSA-73g8-5h73-26h4"],"title":"hpke-js is a Hybrid Public Key Encryption (HPKE) module built on top of Web Cryptography API. Prior to version 1.7.5, the public SenderContext Seal() API has a race condition which allows for the same AEAD nonce to be re-used for multiple S…","description":"hpke-js is a Hybrid Public Key Encryption (HPKE) module built on top of Web Cryptography API. Prior to version 1.7.5, the public SenderContext Seal() API has a race condition which allows for the same AEAD nonce to be re-used for multiple Seal() calls. This can lead to complete loss of Confidentiality and Integrity of the produced messages. This issue has been patched in version 1.7.5.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":null}],"references":["https://github.com/dajiaji/hpke-js/security/advisories/GHSA-73g8-5h73-26h4","https://github.com/dajiaji/hpke-js/commit/94a767c9b9f37ce48d5cd86f7017d8cacd294aaf","https://github.com/dajiaji/hpke-js/blob/b7fd3592c7c08660c98289d67c6bb7f891af75c4/packages/core/src/senderContext.ts#L22-L34"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2025-198319","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Nov 21, 2025, 6:47:19 PM","dateUpdated":"Nov 21, 2025, 7:01:11 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2025-198319","identifiers":["EUVD-2025-198319","CVE-2025-64767","GHSA-73g8-5h73-26h4"]},"retained":false,"historicalAffected":[]},{"revision":"dfb4bdcf328f4a8c8dceb6549d397c1e","observedAt":"2026-10-25T03:17:36.152+00:00","statement":{"source":"nvd","id":"CVE-2025-64767","aliases":[],"title":"hpke-js is a Hybrid Public Key Encryption (HPKE) module built on top of Web Cryptography API. Prior to version 1.7.5, the public SenderContext Seal() API has a race condition which allows for the same AEAD nonce to be re-used for multiple S…","description":"hpke-js is a Hybrid Public Key Encryption (HPKE) module built on top of Web Cryptography API. Prior to version 1.7.5, the public SenderContext Seal() API has a race condition which allows for the same AEAD nonce to be re-used for multiple Seal() calls. This can lead to complete loss of Confidentiality and Integrity of the produced messages. This issue has been patched in version 1.7.5.","state":0,"publishedAt":"2025-11-21T19:16:03.497+00:00","modifiedAt":"2026-10-18T20:10:00.11+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":"CRITICAL"}],"references":["https://github.com/dajiaji/hpke-js/blob/b7fd3592c7c08660c98289d67c6bb7f891af75c4/packages/core/src/senderContext.ts#L22-L34","https://github.com/dajiaji/hpke-js/commit/94a767c9b9f37ce48d5cd86f7017d8cacd294aaf","https://github.com/dajiaji/hpke-js/security/advisories/GHSA-73g8-5h73-26h4"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2025-64767","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-323"],"productCriteria":[],"sourceDates":{"published":"2025-11-21T19:16:03.497","lastModified":"2026-10-18T20:10:00.110"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2025-64767","identifiers":["CVE-2025-64767"]},"retained":false,"historicalAffected":[]},{"revision":"a31fb6f58c4c4464a20270155d058594","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-73g8-5h73-26h4","aliases":["CVE-2025-64767"],"title":"@hpke/core reuses AEAD nonces","description":"### Summary\n\nThe public SenderContext Seal() API has a race condition which allows for the same AEAD nonce to be re-used for multiple Seal() calls. This can lead to complete loss of Confidentiality and Integrity of the produced messages.\n\n### Details\n\nThe SenderContext Seal() [implementation](https://github.com/dajiaji/hpke-js/blob/b7fd3592c7c08660c98289d67c6bb7f891af75c4/packages/core/src/senderContext.ts#L22-L34) allows for concurrent executions to trigger `computeNonce()` with the same sequence number. This results in the same nonce being used in the suite's AEAD.\n\n### PoC\n\nThis code reproduces the issue (and also checks for more things that could be wrong with the implementation).\n\n```js\nimport { CipherSuite, KdfId, AeadId, KemId } from \"hpke-js\";\n\nconst suite = new CipherSuite({\n  kem: KemId.DhkemP256HkdfSha256,\n  kdf: KdfId.HkdfSha256,\n  aead: AeadId.Aes128Gcm,\n});\n\nconst keypair = await suite.kem.generateKeyPair();\nconst skR = keypair.privateKey;\nconst pkR = keypair.publicKey;\n\nconst sender = await suite.createSenderContext({\n  recipientPublicKey: pkR,\n});\n\nconst [message0, message1] = await Promise.all([\n  sender.seal(\n    new TextEncoder().encode(\"Secret message 1: Attack at dawn\").buffer\n  ),\n  sender.seal(\n    new TextEncoder().encode(\"Secret message 2: Withdraw troops\").buffer\n  ),\n]);\n\nconst recipient = await suite.createRecipientContext({\n  recipientKey: skR,\n  enc: sender.enc,\n});\n\nconst plaintext0 = await recipient.open(message0);\nconsole.log(\"✓ Decrypted message seq=0\", new TextDecoder().decode(plaintext0));\n\ntry {\n  console.log(\n    \"✓ Decrypted message seq=1\",\n    new TextDecoder().decode(await recipient.open(message1))\n  );\n  console.log(\"\\n✓ nonce-reuse reproduction completed, code is NOT vulnerable\");\n} catch (error) {\n  // re-sequence the recipient to verify same nonce was used for two messages\n  recipient._ctx.seq = 0;\n  console.log(\n    \"❌ Decrypted a different message with seq=0\",\n    new TextDecoder().decode(await recipient.open(message1))\n  );\n\n  console.log(\n    \"\\n✓ nonce-reuse reproduction completed, code is vulnerable, nonces are reused when concurrent calls to .seal() are used\"\n  );\n}\n\n// Test that failed Open() doesn't increment sequence\nconst recipient2 = await suite.createRecipientContext({\n  recipientKey: skR,\n  enc: sender.enc,\n});\n\nconst invalidMessage = new Uint8Array(message0.byteLength);\ninvalidMessage.set(new Uint8Array(message0));\ninvalidMessage[0] ^= 0xff; // Corrupt the first byte\n\ntry {\n  await recipient2.open(invalidMessage.buffer);\n} catch {}\n\n// Now try to open the first valid message - should still work with seq=0\ntry {\n  await recipient2.open(message0);\n  console.log(\"✓ Successfully decrypted message with seq=0 after failed open()\");\n  console.log(\"✓ Failed open() did NOT increment sequence\");\n} catch (error) {\n  console.log(\"❌ Failed to decrypt message - sequence was incorrectly incremented\");\n}\n\n// Test that same message produces same ciphertext due to nonce reuse\nconst sender2 = await suite.createSenderContext({\n  recipientPublicKey: pkR,\n});\n\nconst sameMessage = new TextEncoder().encode(\"Identical message\").buffer;\nconst [cipher0, cipher1] = await Promise.all([\n  sender2.seal(sameMessage),\n  sender2.seal(sameMessage),\n]);\n\nconst cipher0Array = new Uint8Array(cipher0);\nconst cipher1Array = new Uint8Array(cipher1);\n\nlet identical = true;\nif (cipher0Array.length !== cipher1Array.length) {\n  identical = false;\n} else {\n  for (let i = 0; i < cipher0Array.length; i++) {\n    if (cipher0Array[i] !== cipher1Array[i]) {\n      identical = false;\n      break;\n    }\n  }\n}\n\nif (identical) {\n  console.log(\"\\n❌ Same message produced IDENTICAL ciphertext (nonce reuse confirmed)\");\n} else {\n  console.log(\"\\n✓ Same message produced different ciphertext (nonces are unique)\");\n}\n```\n\n### Recommendation\n\nImplement a synchronization mechanism such that only one seal()/open() per context can be executed at a time.\n\n### Notes\n\nRefs: https://github.com/hpkewg/hpke/issues/38\n\n> https://www.rfc-editor.org/rfc/rfc9180.html#section-9.7.5\n> The AEADs specified in this document are not secure in case of nonce reuse.\n\n> https://www.rfc-editor.org/rfc/rfc9180.html#section-5-6\n> A context is an implementation-specific structure that encodes the AEAD algorithm and key in use, and manages the nonces used so that the same nonce is not used with multiple plaintexts.\n\nThe context implementation in @hpke/core is not correct given its AEAD Seal() is awaited/asynchronous.","state":0,"publishedAt":"2025-11-20T17:36:13+00:00","modifiedAt":"2025-11-21T22:18:25+00:00","affected":[{"ecosystem":"npm","name":"@hpke/core","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"1.7.5"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"CRITICAL"}],"references":["https://github.com/dajiaji/hpke-js/security/advisories/GHSA-73g8-5h73-26h4","https://nvd.nist.gov/vuln/detail/CVE-2025-64767","https://github.com/dajiaji/hpke-js/commit/94a767c9b9f37ce48d5cd86f7017d8cacd294aaf","https://github.com/dajiaji/hpke-js","https://github.com/dajiaji/hpke-js/blob/b7fd3592c7c08660c98289d67c6bb7f891af75c4/packages/core/src/senderContext.ts#L22-L34"],"sourceUrl":"https://github.com/advisories/GHSA-73g8-5h73-26h4","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-73g8-5h73-26h4","identifiers":["GHSA-73g8-5h73-26h4","CVE-2025-64767"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-09T06:02:15.5744295+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-09T06:02:15.5744295+00:00","lastSuccessAt":"2026-11-09T06:02:15.8100724+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.8100756+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-24e6fde7b744113daefb8f6135035fb8a5c69c9617c9c0d40574a0376532ffd3-61bf15172f364246efc204ad9b25e3f89710939e13c23b3efb3d009b5fdad808","complete":true,"records":421290,"lastAttemptAt":"2026-11-09T06:02:14.4940664+00:00","lastSuccessAt":"2026-11-09T05:02:14.5253969+00:00","error":"HttpRequestException","lastVerifiedAt":"2026-11-09T05:02:14.5383867+00:00","snapshotPublishedAt":"2026-11-09T04:29:38+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-52f0bd58a8564ba89a1952b43ef3bc92","complete":false,"records":13654,"lastAttemptAt":"2026-11-09T06:14:09.0160642+00:00","lastSuccessAt":"2026-11-09T06:14:09.013+00:00","error":"8 identifier lookups failed; latest failures include HTTP 403. Other identifiers were checked independently.","lastVerifiedAt":"2026-11-09T06:14:09.013+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13674,"expectedIdentifiers":13706,"failedIdentifiers":8},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-09T06:02:15.5744295+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-09T06:02:15.5744295+00:00","lastSuccessAt":"2026-11-09T06:02:15.8108397+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.81084+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-5a44a451442747cb81d83104fe1e7771","complete":true,"records":13666,"lastAttemptAt":"2026-11-09T06:02:16.371904+00:00","lastSuccessAt":"2026-11-09T02:08:52.274+00:00","error":null,"lastVerifiedAt":"2026-11-09T02:08:52.274+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13706,"expectedIdentifiers":13706,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-980593e6977a6d1b4fb1eed5a1ffe88a468736f89f0a06f710924ad59132c023","complete":true,"records":9914,"lastAttemptAt":"2026-11-09T06:02:15.5156789+00:00","lastSuccessAt":"2026-11-08T11:07:07.068788+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.5156789+00:00","snapshotPublishedAt":"2026-11-08T11:02:46+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-fde804134ecdda0ddd5ff5c26ee1fff5a6fa659311f7ef2e51c6ad54964db0e2","complete":true,"records":1971,"lastAttemptAt":"2026-11-09T06:02:14.6970768+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:14.6970768+00:00","snapshotPublishedAt":"2026-11-06T18:17:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-f6d341f4320a5a0c059c28102ee651c3dd06abc87b84d2bafa4e2a823ec07d35","complete":true,"records":3056,"lastAttemptAt":"2026-11-09T06:02:15.5284383+00:00","lastSuccessAt":"2026-11-09T05:02:23.1539412+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.5284383+00:00","snapshotPublishedAt":"2026-11-09T04:47:48+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-6a1c845b1938b1aa788f0e95c9ac8a8d5a1f07caed5d155840b0616b548c1455","complete":true,"records":231296,"lastAttemptAt":"2026-11-09T06:02:15.4064738+00:00","lastSuccessAt":"2026-11-09T04:03:49.859595+00:00","error":null,"lastVerifiedAt":"2026-11-09T06:02:15.4064738+00:00","snapshotPublishedAt":"2026-11-09T03:33:06+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}