Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Amend Protocol to Always Require Fully-Canonical Signatures #3042

Closed
mDuo13 opened this issue Aug 12, 2019 · 3 comments
Closed

Amend Protocol to Always Require Fully-Canonical Signatures #3042

mDuo13 opened this issue Aug 12, 2019 · 3 comments
Labels
Good First Issue Great issue for a new contributor Tx Change

Comments

@mDuo13
Copy link
Collaborator

mDuo13 commented Aug 12, 2019

Summary

Despite being mostly fixed in 2014, transaction malleability is still theoretically a problem today, because you have to opt in to protection from it by setting tfFullyCanonicalSig. We can fix this with an amendment that makes non-fully-canonical signatures invalid regardless of transaction flags.

Background

The tfFullyCanonicalSig flag was created to allow backwards compatibility with transactions signed with old signing logic that didn't create fully-canonical signatures. This design leaves all transactions valid, but makes full protection from transaction malleability (sort-of) opt-in.

As far as I know, every tool in use today generates fully-canonical signatures, but malicious actors could still convert transactions to non-fully-canonical signatures, resulting in a different hash, if those transactions don't have tfFullyCanonicalSig enabled. This could be used to trick naive transaction submission logic into sending the same payment multiple times.

By default, rippled's sign method supplies a Flags field with tfFullyCanonicalSig enabled if you don't provide a Flags field. However, tfFullyCanonicalSig won't be enabled in the following cases:

  • If you use ripple-lib's signing functionality without "preparing" the transaction first (see also: ripple-lib PR#1028)
  • If you multi-sign using rippled's sign_for method and didn't explicitly set the tfFullyCanonicalFlag
  • If you use rippled's sign method but explicitly supply a Flags field that doesn't include tfFullyCanonicalSig—for example, if you're using another flag, and you don't bitwise-OR it with the tfFullyCanonicalSig value.
  • If you're using your own signing logic that doesn't supply tfFullyCanonicalSig.

This state of affairs requires users to take extra steps to protect themselves against transaction malleability in some cases, and leaves many transactions vulnerable because users forgot or misunderstood the necessary steps.

Proposed Solution

Create an amendment named RequireFullyCanonicalSig (or something along those lines). With this amendment enabled, non-fully-canonical transaction signatures are always considered invalid regardless of whether tfFullyCanonicalSig is specified. (Basically, transactions are treated like tfFullyCanonicalSig is enabled even if it isn't.)

Compatibility with Legacy Transactions

If there are any tools today that create non-fully-canonical signatures by default, those tools break. Both rippled (v0.24.0?) and ripple-lib (v0.9.0?) have created only fully-canonical signatures since 2014. I'm not familiar with any tools that do not create fully-canonical signatures.

Any transactions that were signed in a non-fully-canonical way are no longer valid and cannot be successfully submitted as-is. These could be transactions that were signed in or before early 2014 and put "in cold storage" indefinitely without being submitted. It is not clear if there are any such transactions in existence or how many such transactions would still be valid under current transaction processing rules because of other breaking changes.

If necessary, we could publish a tool that can convert non-fully-canonical signatures to fully-canonical signatures. Basically, this tool would take advantage of the malleability of those transactions to make fully-canonical variants of them without needing anything beyond the signed blob of the transaction itself. This would of course result in a slightly different blob and a different hash, but anyone who has such transactions in cold storage could use this tool to convert them to fully-canonical signatures.

It would probably be advisable not to publish the tool before the amendment became enabled, since it basically would provide sample code for several steps of the existing exploit against transactions not using tfFullyCanonicalSig.

However, it remains to be seen whether such a tool is necessary at all since the existence of any such cold-storage non-fully-canonical transactions is hypothetical.

@nbougalis
Copy link
Contributor

This has been merged as ec13704 and the RequireFullyCanonicalSig amendment was activated with transaction 94D8B158E948148B949CC3C35DD5DC4791D799E1FD5D3CE0E570160EDEF947D3 on the mainnet.

@BeliyBro33
Copy link

Good day! I have an old transaction without a flag, how can I set it?

@ximinez
Copy link
Collaborator

ximinez commented Jan 14, 2025

Good day! I have an old transaction without a flag, how can I set it?

See #5244 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good First Issue Great issue for a new contributor Tx Change
Projects
None yet
Development

No branches or pull requests

4 participants