{"id":"CVE-2026-44714","aliases":["EUVD-2026-30571","GHSA-hfcf-v2f8-x9pc"],"status":"published","title":"bitcoinj: ScriptExecution P2PKH/P2WPKH Verification Bypass","description":"The bitcoinj library is a Java implementation of the Bitcoin protocol. Prior to 0.17.1, ScriptExecution.correctlySpends() contains two fast-path verification bugs for standard P2PKH and native P2WPKH spends in core/src/main/java/org/bitcoinj/script/ScriptExecution.java. In both branches, bitcoinj verifies an attacker-controlled signature/public-key pair but fails to verify that the public key is the one committed to by the output being spent. As a result, any attacker keypair can satisfy bitcoinj's local verification for arbitrary P2PKH and P2WPKH outputs. This vulnerability is fixed in 0.17.1.","severity":{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.0027,"percentile":0.19354,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":true,"fix_available":true},"cwes":["CWE-347"],"published":"2026-05-08T17:43:06Z","modified":"2026-10-28T11:01:06Z","exploits":[{"source":"pocgithub","id":"dntaskmehow/BABEF","title":"dntaskmehow/BABEF","date":"2026-10-21","url":"https://github.com/dntaskmehow/BABEF"}],"fixes":[{"ecosystem":"Maven","package":"org.bitcoinj:bitcoinj-core","fixed_in":["0.17.1"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Maven","package":"org.bitcoinj:bitcoinj-core","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.15"},{"fixed":"0.17.1"}]}]},{"source":"osv","ecosystem":"Maven","package":"org.bitcoinj:bitcoinj-core","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.15"},{"fixed":"0.17.1"}]}],"versions":["0.15","0.15.1","0.15.10","0.15.2","0.15.3","0.15.4","0.15.5","0.15.6","0.15.7","0.15.8","0.15.9","0.16","0.16-beta1","0.16-beta2","0.16-rc1","0.16.1","0.16.2","0.16.3","0.16.4","0.16.5","0.17","0.17-alpha1","0.17-alpha2","0.17-alpha3","0.17-alpha4","0.17-alpha5","0.17-beta1","0.17-rc1","0.17-rc2","0.17-rc3"]}],"products":[{"vendor":"bitcoinj","product":"bitcoinj"}],"references":[{"url":"https://github.com/bitcoinj/bitcoinj/security/advisories/GHSA-hfcf-v2f8-x9pc","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/bitcoinj/bitcoinj/commit/2bc5653c41d260d840692bc554690d4d79208f9c","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/bitcoinj/bitcoinj/commit/b575a682acf614b9ff95cacbdeb48f86c3ababe0","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/bitcoinj/bitcoinj/releases/tag/v0.17.1","tags":["web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44714","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-hfcf-v2f8-x9pc"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/44xxx/CVE-2026-44714.json","tags":["advisory"]},{"url":"https://github.com/bitcoinj/bitcoinj","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-44714","title":"bitcoinj: ScriptExecution P2PKH/P2WPKH Verification Bypass","description":"The bitcoinj library is a Java implementation of the Bitcoin protocol. Prior to 0.17.1, ScriptExecution.correctlySpends() contains two fast-path verification bugs for standard P2PKH and native P2WPKH spends in core/src/main/java/org/bitcoinj/script/ScriptExecution.java. In both branches, bitcoinj verifies an attacker-controlled signature/public-key pair but fails to verify that the public key is the one committed to by the output being spent. As a result, any attacker keypair can satisfy bitcoinj's local verification for arbitrary P2PKH and P2WPKH outputs. This vulnerability is fixed in 0.17.1.","status":"published","published":"2026-05-15T16:51:11.865Z","modified":"2026-05-16T01:13:51.811Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","level":"high","assessor":"cna"}],"cwes":["CWE-347"],"updated_at":"2026-11-02T13:42:49.132798Z"}],"euvd":[{"id":"EUVD-2026-30571","description":"The bitcoinj library is a Java implementation of the Bitcoin protocol. Prior to 0.17.1, ScriptExecution.correctlySpends() contains two fast-path verification bugs for standard P2PKH and native P2WPKH spends in core/src/main/java/org/bitcoinj/script/ScriptExecution.java. In both branches, bitcoinj verifies an attacker-controlled signature/public-key pair but fails to verify that the public key is the one committed to by the output being spent. As a result, any attacker keypair can satisfy bitcoinj's local verification for arbitrary P2PKH and P2WPKH outputs. This vulnerability is fixed in 0.17.1.","status":"published","published":"2026-05-15T16:51:11Z","modified":"2026-05-16T01:13:51Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","level":"high"}],"updated_at":"2026-11-02T19:04:27.676923Z"}],"ghsa":[{"id":"GHSA-hfcf-v2f8-x9pc","title":"bitcoinj has a ScriptExecution P2PKH/P2WPKH Verification Bypass","description":"### Summary\n`ScriptExecution.correctlySpends()` contains two fast-path verification bugs for standard `P2PKH` and native `P2WPKH` spends in `core/src/main/java/org/bitcoinj/script/ScriptExecution.java`.\n\nIn both branches, bitcoinj verifies an attacker-controlled signature/public-key pair but fails to verify that the public key is the one committed to by the output being spent. As a result, any attacker keypair can satisfy bitcoinj's local verification for arbitrary `P2PKH` and `P2WPKH` outputs.\n\nThis doesn't affect the SPV (simple payment verification) trust model, as this model follows PoW and doesn't verify input signatures at all.\n\n### Details\nThe issue is in the optimized branches of `ScriptExecution.correctlySpends(...)`.\n\nIn the `P2PKH` fast path at `core/src/main/java/org/bitcoinj/script/ScriptExecution.java:1042`, the code:\n\n- parses the attacker-supplied signature from `scriptSig`\n- parses the attacker-supplied public key from `scriptSig`\n- computes the sighash against the victim output's `scriptPubKey`\n- checks only `pubkey.verify(sigHash, signature)`\n\nIt never enforces the missing `P2PKH` binding:\n\n- `HASH160(pubkey) == ScriptPattern.extractHashFromP2PKH(scriptPubKey)`\n\nThat means the `OP_DUP OP_HASH160 \u003chash\u003e OP_EQUALVERIFY OP_CHECKSIG` semantics are not actually enforced in this fast path.\n\nRelevant code:\n\n```java\n} else if (ScriptPattern.isP2PKH(scriptPubKey)) {\n    if (chunks.size() != 2)\n        throw new ScriptException(...);\n    TransactionSignature signature;\n    try {\n        byte[] data = Objects.requireNonNull(chunks.get(0).data);\n        signature = TransactionSignature.decodeFromBitcoin(data, true, true);\n    } catch (SignatureDecodeException x) {\n        throw new ScriptException(...);\n    }\n    ECKey pubkey = ECKey.fromPublicOnly(Objects.requireNonNull(chunks.get(1).data));\n    Sha256Hash sigHash = txContainingThis.hashForSignature(scriptSigIndex, scriptPubKey,\n            signature.sigHashMode(), false);\n    boolean validSig = pubkey.verify(sigHash, signature);\n    if (!validSig)\n        throw new ScriptException(...);\n}\n```\n\nIn the native `P2WPKH` fast path at `core/src/main/java/org/bitcoinj/script/ScriptExecution.java:1023`, the bug is similar. The code:\n\n- reads the attacker-supplied pubkey from `witness`\n- builds `scriptCode` from that attacker pubkey with `ScriptBuilder.createP2PKHOutputScript(pubkey)`\n- computes the BIP143 sighash using that attacker-derived `scriptCode`\n- verifies the signature against the attacker pubkey\n\nIt never enforces:\n\n- `HASH160(pubkey) == ScriptPattern.extractHashFromP2WH(scriptPubKey)`\n\nSo for `P2WPKH`, the attacker controls both the pubkey and the `scriptCode` used for signing.\n\nRelevant code:\n\n```java\nif (ScriptPattern.isP2WPKH(scriptPubKey)) {\n    Objects.requireNonNull(witness);\n    if (witness.getPushCount() \u003c 2)\n        throw new ScriptException(...);\n    TransactionSignature signature;\n    try {\n        signature = TransactionSignature.decodeFromBitcoin(witness.getPush(0), true, true);\n    } catch (SignatureDecodeException x) {\n        throw new ScriptException(...);\n    }\n    ECKey pubkey = ECKey.fromPublicOnly(witness.getPush(1));\n    Script scriptCode = ScriptBuilder.createP2PKHOutputScript(pubkey);\n    Sha256Hash sigHash = txContainingThis.hashForWitnessSignature(scriptSigIndex, scriptCode, value,\n            signature.sigHashMode(), false);\n    boolean validSig = pubkey.verify(sigHash, signature);\n    if (!validSig)\n        throw new ScriptException(...);\n}\n```\n\nAffected call sites include:\n\n- `core/src/main/java/org/bitcoinj/core/TransactionInput.java:546`\n- `core/src/main/java/org/bitcoinj/wallet/Wallet.java:4520`\n- `core/src/main/java/org/bitcoinj/signers/LocalTransactionSigner.java:84`\n- `core/src/main/java/org/bitcoinj/signers/CustomTransactionSigner.java:77`\n\nThese call sites use `correctlySpends()` for transaction/input validation and pre-signing checks. Any application that treats a successful result from this path as proof that a spend is valid is affected.\n\n### Fix\nThe issue is fixed on the `release-0.17` branch via 2bc5653c41d260d840692bc554690d4d79208f9c, and on `master` via b575a682acf614b9ff95cacbdeb48f86c3ababe0. A 0.17.1 maintenance release has been made available on Maven Central.","status":"published","published":"2026-05-08T17:43:06Z","modified":"2026-05-15T23:49:54Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","level":"high"}],"cwes":["CWE-347"],"updated_at":"2026-11-02T14:40:10.269075Z"}],"nvd":[{"id":"CVE-2026-44714","description":"The bitcoinj library is a Java implementation of the Bitcoin protocol. Prior to 0.17.1, ScriptExecution.correctlySpends() contains two fast-path verification bugs for standard P2PKH and native P2WPKH spends in core/src/main/java/org/bitcoinj/script/ScriptExecution.java. In both branches, bitcoinj verifies an attacker-controlled signature/public-key pair but fails to verify that the public key is the one committed to by the output being spent. As a result, any attacker keypair can satisfy bitcoinj's local verification for arbitrary P2PKH and P2WPKH outputs. This vulnerability is fixed in 0.17.1.","status":"published","published":"2026-05-15T17:16:47.933Z","modified":"2026-06-17T10:51:15.987Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","level":"high","assessor":"secondary"}],"cwes":["CWE-347"],"updated_at":"2026-11-02T14:12:19.39893Z"}],"osv":[{"id":"CVE-2026-44714","title":"bitcoinj: ScriptExecution P2PKH/P2WPKH Verification Bypass","description":"The bitcoinj library is a Java implementation of the Bitcoin protocol. Prior to 0.17.1, ScriptExecution.correctlySpends() contains two fast-path verification bugs for standard P2PKH and native P2WPKH spends in core/src/main/java/org/bitcoinj/script/ScriptExecution.java. In both branches, bitcoinj verifies an attacker-controlled signature/public-key pair but fails to verify that the public key is the one committed to by the output being spent. As a result, any attacker keypair can satisfy bitcoinj's local verification for arbitrary P2PKH and P2WPKH outputs. This vulnerability is fixed in 0.17.1.","status":"published","published":"2026-05-15T16:51:11.865Z","modified":"2026-10-28T11:01:06.288293105Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","level":"high"}],"cwes":["CWE-347"],"updated_at":"2026-11-02T15:45:05.172514Z"},{"id":"GHSA-hfcf-v2f8-x9pc","title":"bitcoinj has a ScriptExecution P2PKH/P2WPKH Verification Bypass","description":"### Summary\n`ScriptExecution.correctlySpends()` contains two fast-path verification bugs for standard `P2PKH` and native `P2WPKH` spends in `core/src/main/java/org/bitcoinj/script/ScriptExecution.java`.\n\nIn both branches, bitcoinj verifies an attacker-controlled signature/public-key pair but fails to verify that the public key is the one committed to by the output being spent. As a result, any attacker keypair can satisfy bitcoinj's local verification for arbitrary `P2PKH` and `P2WPKH` outputs.\n\nThis doesn't affect the SPV (simple payment verification) trust model, as this model follows PoW and doesn't verify input signatures at all.\n\n### Details\nThe issue is in the optimized branches of `ScriptExecution.correctlySpends(...)`.\n\nIn the `P2PKH` fast path at `core/src/main/java/org/bitcoinj/script/ScriptExecution.java:1042`, the code:\n\n- parses the attacker-supplied signature from `scriptSig`\n- parses the attacker-supplied public key from `scriptSig`\n- computes the sighash against the victim output's `scriptPubKey`\n- checks only `pubkey.verify(sigHash, signature)`\n\nIt never enforces the missing `P2PKH` binding:\n\n- `HASH160(pubkey) == ScriptPattern.extractHashFromP2PKH(scriptPubKey)`\n\nThat means the `OP_DUP OP_HASH160 \u003chash\u003e OP_EQUALVERIFY OP_CHECKSIG` semantics are not actually enforced in this fast path.\n\nRelevant code:\n\n```java\n} else if (ScriptPattern.isP2PKH(scriptPubKey)) {\n    if (chunks.size() != 2)\n        throw new ScriptException(...);\n    TransactionSignature signature;\n    try {\n        byte[] data = Objects.requireNonNull(chunks.get(0).data);\n        signature = TransactionSignature.decodeFromBitcoin(data, true, true);\n    } catch (SignatureDecodeException x) {\n        throw new ScriptException(...);\n    }\n    ECKey pubkey = ECKey.fromPublicOnly(Objects.requireNonNull(chunks.get(1).data));\n    Sha256Hash sigHash = txContainingThis.hashForSignature(scriptSigIndex, scriptPubKey,\n            signature.sigHashMode(), false);\n    boolean validSig = pubkey.verify(sigHash, signature);\n    if (!validSig)\n        throw new ScriptException(...);\n}\n```\n\nIn the native `P2WPKH` fast path at `core/src/main/java/org/bitcoinj/script/ScriptExecution.java:1023`, the bug is similar. The code:\n\n- reads the attacker-supplied pubkey from `witness`\n- builds `scriptCode` from that attacker pubkey with `ScriptBuilder.createP2PKHOutputScript(pubkey)`\n- computes the BIP143 sighash using that attacker-derived `scriptCode`\n- verifies the signature against the attacker pubkey\n\nIt never enforces:\n\n- `HASH160(pubkey) == ScriptPattern.extractHashFromP2WH(scriptPubKey)`\n\nSo for `P2WPKH`, the attacker controls both the pubkey and the `scriptCode` used for signing.\n\nRelevant code:\n\n```java\nif (ScriptPattern.isP2WPKH(scriptPubKey)) {\n    Objects.requireNonNull(witness);\n    if (witness.getPushCount() \u003c 2)\n        throw new ScriptException(...);\n    TransactionSignature signature;\n    try {\n        signature = TransactionSignature.decodeFromBitcoin(witness.getPush(0), true, true);\n    } catch (SignatureDecodeException x) {\n        throw new ScriptException(...);\n    }\n    ECKey pubkey = ECKey.fromPublicOnly(witness.getPush(1));\n    Script scriptCode = ScriptBuilder.createP2PKHOutputScript(pubkey);\n    Sha256Hash sigHash = txContainingThis.hashForWitnessSignature(scriptSigIndex, scriptCode, value,\n            signature.sigHashMode(), false);\n    boolean validSig = pubkey.verify(sigHash, signature);\n    if (!validSig)\n        throw new ScriptException(...);\n}\n```\n\nAffected call sites include:\n\n- `core/src/main/java/org/bitcoinj/core/TransactionInput.java:546`\n- `core/src/main/java/org/bitcoinj/wallet/Wallet.java:4520`\n- `core/src/main/java/org/bitcoinj/signers/LocalTransactionSigner.java:84`\n- `core/src/main/java/org/bitcoinj/signers/CustomTransactionSigner.java:77`\n\nThese call sites use `correctlySpends()` for transaction/input validation and pre-signing checks. Any application that treats a successful result from this path as proof that a spend is valid is affected.\n\n### Fix\nThe issue is fixed on the `release-0.17` branch via 2bc5653c41d260d840692bc554690d4d79208f9c, and on `master` via b575a682acf614b9ff95cacbdeb48f86c3ababe0. A 0.17.1 maintenance release has been made available on Maven Central.","status":"published","published":"2026-05-08T17:43:06Z","modified":"2026-05-16T00:08:27.144498Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N","level":"high"}],"cwes":["CWE-347"],"updated_at":"2026-11-02T15:46:48.920784Z"}]}}
