Smiley face
Weather     Live Markets

Bitcoin Core Moves to Close SIGHASH_SINGLE Blind Spot in PSBT Workflows

A Subtle Flaw in Bitcoin’s Signature Machinery

Bitcoin’s security model is built on a promise that looks simple on paper: a digital signature must reflect exactly what the signer authorized. In practice, that promise depends on a set of technical rules that are easy to overlook, especially when a transaction is assembled in one place and signed in another. The latest case involves SIGHASH_SINGLE, a Bitcoin signing mode designed to link a specific input to the output at the same index. That mechanism can be useful in certain contract-style transactions, but it carries an edge case that has drawn renewed attention from Bitcoin Core developers. If the transaction does not include an output at the corresponding position, the strength of the cryptographic commitment changes, and in some cases it can break down in ways that are not immediately obvious. The result is a vulnerability that is less about stolen keys and more about broken trust: a signature may not actually commit to the payment details the user intended to approve. Bitcoin Core has now moved to close that gap by changing how the software handles affected signing requests, specifically within the Partially Signed Bitcoin Transaction workflow, better known as PSBT. The change was merged into the project’s development branch on Sept. 25, and it targets a subtle but significant weakness in how certain Bitcoin inputs are signed.

The problem is rooted in the way Bitcoin defines signature hash types. These hash types tell the signature algorithm which parts of a transaction must be committed to in the cryptographic signature. SIGHASH_ALL, for example, commits to every input and output in the transaction. SIGHASH_SINGLE takes a different approach. It commits to one input and one output, both at the same positional index. This can be useful for specialized transaction structures where each input is meant to fund a corresponding output. But SIGHASH_SINGLE has an unusual requirement: if the output at the matching index does not exist, the protocol does not simply fail. Instead, it produces a signature with a different, weaker meaning. For legacy Bitcoin inputs, that missing-output case can generate a signature over a fixed hash value — a value that does not represent the actual transaction output. Bitcoin Core developers have warned that this signature may be reusable against other unspent outputs controlled by the same key, provided the same structural conditions apply. That is a serious concern for wallet developers, because a signature that can be replayed is not a signature that can be trusted. Users might believe they are authorizing one transaction, only to find that the same cryptographic material works in another context entirely.

For Legacy Inputs, a Signature That Can Be Reused

Legacy inputs are the old guard of Bitcoin’s transaction ecosystem. They predate SegWit and cover address formats such as P2PKH and P2SH. These inputs rely on a signature model that is highly flexible but also less constrained than newer formats. When SIGHASH_SINGLE is used on a legacy input and the corresponding output is missing, the signature is not bound to an actual payment destination. It is generated over a fixed value that is essentially independent of the transaction’s output data. That may sound like a minor technical nuance, but it has real consequences. If a signature is produced over a fixed hash value, it is not anchored to the specific transaction being signed. Under the right conditions, that same signature could be applied to a different transaction that spends a different unspent output controlled by the same private key. The Bitcoin Core developers described this as a potential reuse issue, noting that the signature may be valid against other outputs when the same structural conditions are present. In plain terms, a signature intended for one payment could potentially be moved to another payment without the signer’s knowledge.

What makes this especially troubling is that the problem is not visible to most users. A wallet interface can display a recipient address, an amount, and a fee, all of which look normal. But the signature itself may not commit to those displayed details. The software that builds the transaction controls the narrative, and if that software is malicious or compromised, it can present one payment to the user while setting up the transaction in a way that changes what is actually signed. The private keys are never exposed. The cryptography is not broken. The problem is that the signing mode does not bind the signature to the full transaction structure. That is a logic gap, not a math gap, and it is exactly the kind of issue that security researchers worry about because it can slip through even well-designed wallet systems.

SegWit v0: Stronger Protection, but Still Not Fully Bound

SegWit v0 introduced significant improvements to Bitcoin’s transaction handling, and that includes stronger signature commitments. When a SegWit v0 input is signed, the signature commits to the specific coin being spent and its amount. That means the kind of signature reuse that affects legacy inputs is largely neutralized. The signature cannot easily be lifted and applied to a different unspent output, because the commitment includes the UTXO itself. That is a meaningful upgrade in security, and it is one of the reasons SegWit adoption has been widely encouraged. However, the new analysis from Bitcoin Core shows that SegWit v0 is not entirely immune to the SIGHASH_SINGLE edge case. The destination output can remain unbound when the corresponding output position is missing. In other words, the signature still commits to what is being spent, but it may not commit to where the funds are going.

That creates an authorization problem. A hardware wallet or other signing device might display a transaction for approval. The user looks at the recipient address, verifies the amount, and approves. But if the transaction uses SIGHASH_SINGLE with a missing output, the signature that is produced may not cryptographically guarantee that the displayed recipient is locked in. A different recipient could be substituted after the signature is created, without invalidating the signature. This is not the same as the legacy reuse problem, but it is equally dangerous in practice because it undermines the principle of “what you see is what you sign.” For users who rely on hardware wallets to protect them from compromised computers, this is precisely the kind of scenario that keeps security engineers awake at night. The hardware device may do everything right, but if the transaction data it is asked to sign does not include a binding commitment to the destination address, the device cannot fully protect the user.

The broader concern is not limited to any single wallet or device. It applies to any system that constructs transactions and passes them to a separate signer. The signer might be a hardware wallet, an offline computer, or a mobile app. If the transaction format allows the destination to remain unbound, then the signer is being asked to approve a transaction that is not fully defined. That is a fundamental violation of the trust model that makes secure signing possible. Bitcoin Core’s response to this issue is therefore not just a patch for one specific command. It is a reinforcement of a core principle: a valid signature must commit to the transaction details the user actually authorized.

Bitcoin Core Moves the Check Into the Signing Pipeline

Bitcoin Core has long been aware of the risks associated with unusual signature hash types. The raw transaction signing interface already rejected the missing-output SIGHASH_SINGLE case, preventing it from being signed through that particular path. But the PSBT path was a different story. PSBTs, which are defined in Bitcoin Improvement Proposal 174, are designed to carry transaction information between different parties in a signing workflow. They allow a transaction builder to prepare all the necessary data and pass it to a signer without giving that signer control over the private keys. This is how many modern Bitcoin wallets and hardware devices coordinate. The signer receives a PSBT, inspects it, signs what it can, and returns a PSBT that can be finalized by the original builder. It is a powerful system, but it is only as strong as the validation performed at each stage.

The new Bitcoin Core change moves the SIGHASH_SINGLE check into the shared signature-creation logic. That means the protection is no longer limited to the raw transaction interface. It now applies to the PSBT workflow, including the walletprocesspsbt command. When the software encounters a legacy or SegWit v0 input that requests SIGHASH_SINGLE for a missing output index, it will refuse to sign that input. Importantly, the change is selective rather than broad. Other valid inputs in the same PSBT can still be signed. This is a careful approach, because PSBTs often contain multiple inputs from different addresses or different parties. Blocking the entire transaction would be disruptive. Blocking only the affected input preserves the flexibility of the PSBT workflow while ensuring that the insecure configuration never reaches the signing stage.

This matters because PSBTs are not a niche tool. They are the backbone of a wide range of Bitcoin security practices, from multi-signature setups to hardware wallet integrations. The whole point of a PSBT is to let different components of a system play different roles. One component builds the transaction, another approves it, and another broadcasts it. Each component is supposed to act as a check on the others. The new Bitcoin Core change makes it clear that signing must not be delegated to a blind process. If a signing request contains a structural flaw, the signer should refuse it rather than produce a signature that can be used in unexpected ways. That is not just a technical improvement. It is a statement about the standards that Bitcoin’s reference implementation expects from the broader ecosystem.

Why PSBTs Demand a Hard Line on Signing Modes

To understand why this fix is so important, it helps to look at how PSBTs fit into real-world Bitcoin usage. A typical hardware wallet setup involves a computer connected to the internet and a hardware device that stores private keys offline. The computer builds a transaction and creates a PSBT. The hardware device imports that PSBT, displays the relevant details, and asks the user to confirm. Once confirmed, the device signs and exports the PSBT back to the computer. This workflow is designed to ensure that private keys never leave the device and that the user has a final say over what gets signed. But that design relies on a hidden assumption: the signature created by the device must be tied to the exact transaction details displayed on the device. If the signing mode allows the destination output to remain unbound, the device’s approval becomes meaningless.

BIP 174 already tells signers to reject unacceptable signing modes and recommends SIGHASH_ALL when no alternative is specified. SIGHASH_ALL is the safest default because it commits to every input and output in the transaction. It leaves no room for a coordinator to alter the payment details after the signature is produced. But software does not always follow best practices, especially when it encounters unusual transaction types or legacy compatibility requirements. The Bitcoin Core change closes the door explicitly. It prevents the missing-output configuration from reaching the signing stage, regardless of whether the transaction is being signed through a command-line interface, a wallet backend, or a PSBT workflow. The fix reinforces a boundary that wallet developers must enforce independently of key security. A hardware wallet can protect private keys with the best secure element on the market, but if the signing logic does not commit to the full transaction, that protection is incomplete.

The risk is especially pronounced in multi-party transactions, where different participants may not fully trust one another. In a multi-signature arrangement, each signer is expected to verify that the transaction matches the agreement. If a transaction uses SIGHASH_SINGLE with a missing output, one participant could potentially change the destination after other participants have signed. The signature would remain valid, but the transaction would not reflect the agreed terms. That is the kind of subtle manipulation that is difficult to detect and even harder to explain to users who are not familiar with Bitcoin’s internal mechanics. By rejecting the affected signing configuration, Bitcoin Core is helping to ensure that PSBT-based systems do not become vehicles for authorization confusion. The fix is not a new feature. It is a restoration of a fundamental guarantee: a signature should mean one thing and one thing only.

No Confirmed Release Yet: What Wallet Developers Should Do Now

Despite the importance of the fix, users do not yet have a confirmed production release containing the safeguard. The Sept. 25 change was merged into Bitcoin Core’s development branch, but as of Oct. 4, the project’s published release listings had not identified a fixed version or confirmed a backport to an existing release. That creates an awkward window, especially for wallet providers and hardware-signing integrations that depend on Bitcoin Core for their backend signing logic. They cannot simply wait for the next release and assume the problem is solved. They need to review their own handling of SIGHASH_SINGLE requests now, because the risk exists in their own signing paths regardless of what Bitcoin Core does downstream.

For developers, this means auditing the code that builds, validates, and signs PSBTs. It means checking whether signing modes are chosen based on user intent or left to default behavior. It means ensuring that a missing-output SIGHASH_SINGLE request is rejected before it reaches a hardware device, not after. The Bitcoin Core fix is an important step, but it is not a substitute for wallet-level validation. The broader lesson is one that has been repeated many times in the history of Bitcoin: security is not just about protecting private keys. It is also about ensuring that the cryptographic signatures produced by those keys are precise, meaningful, and bound to the exact transaction the user approved. SIGHASH_SINGLE is a niche signing mode, but it is a reminder that even the most obscure parts of a protocol can have real-world consequences. For users, the practical takeaway is simple. Use wallets that favor SIGHASH_ALL by default, be wary of transaction types that require unusual signing modes, and keep signing software updated. In a system built on cryptographic truth, a signature that does not commit to the truth is not a signature worth trusting.

Share.
Leave A Reply