{"id":"CVE-2026-129319","kind":"vulnerability","aliases":["CVE-2026-129319"],"related":[],"title":"create-ecdh: browser ECDH skips key validation, leaking private keys","description":"create-ecdh is a browserifiable implementation of Node.js crypto.createECDH. In versions 4.0.4 and below, the JavaScript implementation (browser.js, used by browser bundlers and on Node.js versions without a working native crypto.createECDH) did not validate peer public keys in ECDH.prototype.computeSecret or ECDH.prototype.setPublicKey. The peer point was multiplied by the local private key without checking that it was on the configured curve or in its prime-order subgroup. An attacker who can submit public keys to a party that reuses a static private key can perform an invalid-curve or small-subgroup attack and recover the private key modulo small factors, eventually recovering the full key via the Chinese Remainder Theorem. For the ed25519 and curve25519 curves, low-order points were also accepted, which could force a predictable shared secret. On modern Node.js, create-ecdh re-exports the native implementation, which is not affected. This issue is fixed in version 4.0.5.","summary":"create-ecdh's JavaScript fallback for Diffie-Hellman key exchange does not check peer public keys before using them. An attacker who can send keys to a party reusing a static private key can recover that key over repeated attempts, or force a predictable shared secret on ed25519 and curve25519.","severity":"high","cvss":8.2,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"create-ecdh","fixed":[],"affected":"","ecosystem":"npm"}],"ecosystems":["npm"],"tags":["browser","crypto","javascript","npm","package"],"not_affected_if":["native-node-crypto","no-static-keys","no-untrusted-peers"],"how_to_check":"- Check the installed version with `npm ls create-ecdh`; versions `4.0.4` and below are affected.\n- Find bundles or servers that use create-ecdh in the browser or on Node.js without a working native crypto.createECDH.\n- Native crypto.createECDH on modern Node.js is not affected.","fix":"- create-ecdh: move to `4.0.5`.","status":"open","published_at":"2026-11-14T07:17:21+00:00","first_seen_at":"2026-11-14T07:27:46+00:00","triaged_at":"2026-11-14T07:28:08+00:00","updated_at":"2026-11-14T07:28:08+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-14T07:28:08Z","model":"claude-haiku-5-5","output":{"fix":"- create-ecdh: move to `4.0.5`.","reach":"network","title":"create-ecdh: browser ECDH skips key validation, leaking private keys","impact":"high","summary":"create-ecdh's JavaScript fallback for Diffie-Hellman key exchange does not check peer public keys before using them. An attacker who can send keys to a party reusing a static private key can recover that key over repeated attempts, or force a predictable shared secret on ed25519 and curve25519.","audience":"developers","category":"package","nicknames":[],"who_cares":["npm","browser","javascript","crypto"],"confidence":0.8,"fix_status":"available","needs_auth":"no","worst_case":"private key recovered or shared secret forced to a predictable value","analyst_note":"","how_to_check":"- Check the installed version with `npm ls create-ecdh`; versions `4.0.4` and below are affected.\n- Find bundles or servers that use create-ecdh in the browser or on Node.js without a working native crypto.createECDH.\n- Native crypto.createECDH on modern Node.js is not affected.","plain_action":"","product_name":"create-ecdh","needs_analyst":false,"not_affected_if":["native-node-crypto","no-static-keys","no-untrusted-peers"],"who_is_affected":"Projects that bundle create-ecdh for browsers, or run it on old Node.js versions without a working native crypto.createECDH, and that reuse a static private key while accepting public keys from others. Modern Node.js re-exports the native implementation, which is not affected, so apps relying only on that path can skip it.","user_interaction":"no","product_ecosystem":"npm","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000778,"input_tokens":4800,"output_tokens":596,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-129319':14A,17A '-2026':13A,16A '4.0.4':90C '4.0.5':233C 'accept':203C 'affect':226C 'also':202C 'attack':48B,147C,172C 'attempt':67B 'browser':4A,21B,99C 'browser.js':96C 'browserifi':83C 'bundler':100C 'check':40B,131C 'chines':188C 'configur':137C 'could':205C 'creat':2A,27B,79C,215C 'create':19A 'create-ecdh':1A,18A,26B,78C,214C 'crypto':22B 'crypto.createecdh':87C,109C 'curv':138C,167C,196C 'curve25519':77B,195C 'cve':12A,15A 'diffi':34B 'diffie-hellman':33B 'ecdh':3A,5A,20A,28B,80C,216C 'ecdh.prototype.computesecret':117C 'ecdh.prototype.setpublickey':119C 'ed25519':75B,193C 'eventu':181C 'exchang':37B 'export':219C 'factor':180C 'fallback':31B 'fix':230C 'forc':69B,206C 'full':184C 'hellman':35B 'implement':84C,95C,222C 'invalid':166C 'invalid-curv':165C 'issu':228C 'javascript':23B,30B,94C 'key':7A,11A,36B,43B,52B,60B,64B,115C,129C,152C,161C,177C,185C 'leak':9A 'local':127C 'low':198C 'low-ord':197C 'modern':212C 'modulo':178C 'multipli':124C 'nativ':108C,221C 'node.js':86C,103C,213C 'npm':24B 'order':144C,199C 'packag':25B 'parti':55B,155C 'peer':41B,113C,121C 'perform':163C 'point':122C,200C 'predict':71B,208C 'prime':143C 'prime-ord':142C 'privat':10A,59B,128C,160C,176C 'public':42B,114C,151C 're':218C 're-export':217C 'recov':62B,174C,182C 'remaind':189C 'repeat':66B 'reus':56B,157C 'secret':73B,210C 'send':51B 'share':72B,209C 'skip':6A 'small':170C,179C 'small-subgroup':169C 'static':58B,159C 'subgroup':145C,171C 'submit':150C 'theorem':190C 'use':45B,97C 'valid':8A,112C 'version':89C,104C,232C 'via':186C 'without':105C,130C 'work':107C","nicknames":[],"mitigations":[],"who_affected":"Projects that bundle create-ecdh for browsers, or run it on old Node.js versions without a working native crypto.createECDH, and that reuse a static private key while accepting public keys from others. Modern Node.js re-exports the native implementation, which is not affected, so apps relying only on that path can skip it.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["createecdh"],"ptokens":["create","ecdh"],"labels":["browser","crypto","high","javascript","npm","package"],"campaign_type":null,"search_a":"'-129319':14A,17A '-2026':13A,16A 'browser':4A 'creat':2A 'create':19A 'create-ecdh':1A,18A 'cve':12A,15A 'ecdh':3A,5A,20A 'key':7A,11A 'leak':9A 'privat':10A 'skip':6A 'valid':8A","search_b":"'attack':48B 'attempt':67B 'browser':21B 'check':40B 'creat':27B 'create-ecdh':26B 'crypto':22B 'curve25519':77B 'diffi':34B 'diffie-hellman':33B 'ecdh':28B 'ed25519':75B 'exchang':37B 'fallback':31B 'forc':69B 'hellman':35B 'javascript':23B,30B 'key':36B,43B,52B,60B,64B 'npm':24B 'packag':25B 'parti':55B 'peer':41B 'predict':71B 'privat':59B 'public':42B 'recov':62B 'repeat':66B 'reus':56B 'secret':73B 'send':51B 'share':72B 'static':58B 'use':45B","search_c":"'4.0.4':90C '4.0.5':233C 'accept':203C 'affect':226C 'also':202C 'attack':147C,172C 'browser':99C 'browser.js':96C 'browserifi':83C 'bundler':100C 'check':131C 'chines':188C 'configur':137C 'could':205C 'creat':79C,215C 'create-ecdh':78C,214C 'crypto.createecdh':87C,109C 'curv':138C,167C,196C 'curve25519':195C 'ecdh':80C,216C 'ecdh.prototype.computesecret':117C 'ecdh.prototype.setpublickey':119C 'ed25519':193C 'eventu':181C 'export':219C 'factor':180C 'fix':230C 'forc':206C 'full':184C 'implement':84C,95C,222C 'invalid':166C 'invalid-curv':165C 'issu':228C 'javascript':94C 'key':115C,129C,152C,161C,177C,185C 'local':127C 'low':198C 'low-ord':197C 'modern':212C 'modulo':178C 'multipli':124C 'nativ':108C,221C 'node.js':86C,103C,213C 'order':144C,199C 'parti':155C 'peer':113C,121C 'perform':163C 'point':122C,200C 'predict':208C 'prime':143C 'prime-ord':142C 'privat':128C,160C,176C 'public':114C,151C 're':218C 're-export':217C 'recov':174C,182C 'remaind':189C 'reus':157C 'secret':210C 'share':209C 'small':170C,179C 'small-subgroup':169C 'static':159C 'subgroup':145C,171C 'submit':150C 'theorem':190C 'use':97C 'valid':112C 'version':89C,104C,232C 'via':186C 'without':105C,130C 'work':107C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-14T06:48:29+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/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","cvss_by":"7ffcee3d-2c14-4c3e-b844-86c6a321a158","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-129319","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-129319","severity":null,"published_at":"2026-11-14T07:17:21+00:00","modified_at":"2026-11-14T07:17:21+00:00","first_seen_at":"2026-11-14T07:27:46+00:00","fetched_at":"2026-11-14T07:27:46+00:00","note":null}],"documents":[{"id":153716,"url":"https://github.com/browserify/createECDH/commit/1cfaf332773237e5fea4b51a2ad3efab4c22bec1","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":153717,"url":"https://github.com/browserify/createECDH/security/advisories/GHSA-32q7-f779-hw5r","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-14T06:48:29+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}