From 0b673dc5c53ec8371b2b476e721ff088e41775ac Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Thu, 20 Dec 2018 16:55:38 -0800 Subject: [PATCH 1/7] Start tx malleability doc --- .../transaction-malleability.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 content/concepts/consensus-network/transaction-malleability.md diff --git a/content/concepts/consensus-network/transaction-malleability.md b/content/concepts/consensus-network/transaction-malleability.md new file mode 100644 index 0000000000..8620913ded --- /dev/null +++ b/content/concepts/consensus-network/transaction-malleability.md @@ -0,0 +1,23 @@ +# Transaction Malleability + +A transaction is "malleable" if it can be changed in any way after being signed, without the keys to sign it. In the XRP Ledger, the **functionality** of a signed transaction cannot change, but in some circumstances a third party _could_ change the signature and identifying hash of a transaction. + +**Use the [tfFullyCanonicalSig flag](transaction-common-fields.html#global-flags)** to guarantee that a transaction is not malleable in any way. Although transactions [signed with Ed25519 keys](cryptographic-keys.html#signing-algorithms) are not vulnerable to this problem, **there is no downside** to using this flag on _all_ transactions. + +## Background + +In the XRP Ledger, all [fields of a transaction](transaction-common-fields.html) must be signed, except the signature itself. Any change to the signed fields, no matter how small, would invalidate the signature, so no part of the transaction can be malleable except for the signature itself. + +For a transaction to be valid, the signature must be canonical, must match the transaction instructions that were signed, and the key pair used to sign it must be one that is [authorized to send transactions on behalf of that account](transaction-basics.html#authorizing-transactions). + +Signatures created with the ECDSA algorithm and secp256k1 curve (the default) must also meet the following requirements: + +- The signature must be properly [DER-encoded data](https://en.wikipedia.org/wiki/X.690#DER_encoding). +- The signature must not have any padding bytes outside the DER-encoded data. +- The signature's component integers must not be negative, and they must not be larger than the secp256k1 modulus. + +Generally speaking, any standard ECDSA implementation handles these requirements automatically. However, with secp256k1, those requirements are insufficient to prevent malleability. + +An ECDSA signature consists of two integers, called R and S. The secp256k1 modulus, called N, is a constant value for all secp256k1 signatures. Specifically, N is the value `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141`. For any given signature `(R,S)`, the signature `(R, N-S)` (that is, using N minus S in place of S) is also valid. Thus, to have _fully_ canonical signatures, one must choose which of the two possibilities is preferred and declare the other to be invalid. This is what the tfFullyCanonicalSig flag does: without that flag enabled, XRP Ledger transactions are valid with either of the two possible signatures; with it, the signature must use the _smaller_ of the two possible values, `S` or `N-S`. + +To calculate a fully-canonical ECDSA signature, one must compare S and N-S From ade5e1622857de05bd1ff3c0054eba3a3584af82 Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Mon, 7 Jan 2019 18:56:05 -0800 Subject: [PATCH 2/7] Tx malleability: add multi-signing case, exploit steps --- .../transaction-malleability.md | 114 ++++++++++++++++-- 1 file changed, 107 insertions(+), 7 deletions(-) diff --git a/content/concepts/consensus-network/transaction-malleability.md b/content/concepts/consensus-network/transaction-malleability.md index 8620913ded..5d78985ac5 100644 --- a/content/concepts/consensus-network/transaction-malleability.md +++ b/content/concepts/consensus-network/transaction-malleability.md @@ -2,22 +2,122 @@ A transaction is "malleable" if it can be changed in any way after being signed, without the keys to sign it. In the XRP Ledger, the **functionality** of a signed transaction cannot change, but in some circumstances a third party _could_ change the signature and identifying hash of a transaction. -**Use the [tfFullyCanonicalSig flag](transaction-common-fields.html#global-flags)** to guarantee that a transaction is not malleable in any way. Although transactions [signed with Ed25519 keys](cryptographic-keys.html#signing-algorithms) are not vulnerable to this problem, **there is no downside** to using this flag on _all_ transactions. +If vulnerable software submits malleable transactions and assumes they can only execute under the original hash, it may lose track of transactions. In the worst case, malicious actors could take advantage of this to steal money from the vulnerable system. + +There are two circumstances that could lead to transaction malleability: + +1. The transaction does not specify the tfFullyCanonicalSig flag on a transaction signed using the default signing algorithm (ECDSA with the secp256k1 curve). + + **Use the [tfFullyCanonicalSig flag](transaction-common-fields.html#global-flags)** to guarantee that a transaction is not malleable in this way. Although transactions [signed with Ed25519 keys](cryptographic-keys.html#signing-algorithms) are not vulnerable to this problem, **there is no downside** to using this flag on _all_ transactions. + +2. The transaction is [multi-signed](multi-signing.html) and has more signatures than necessary. Even if the transaction originally did not have more signatures than necessary, it could be malleable if one of the authorized signers provides an additional signature. + + There is no solution that prevents all variations of this problem. When using multi-signatures, monitor your account for transactions sent even if they have different hashes, and try not to collect more signatures than necessary. + ## Background -In the XRP Ledger, all [fields of a transaction](transaction-common-fields.html) must be signed, except the signature itself. Any change to the signed fields, no matter how small, would invalidate the signature, so no part of the transaction can be malleable except for the signature itself. +In the XRP Ledger, a transaction cannot execute unless: -For a transaction to be valid, the signature must be canonical, must match the transaction instructions that were signed, and the key pair used to sign it must be one that is [authorized to send transactions on behalf of that account](transaction-basics.html#authorizing-transactions). +- All [fields of a transaction](transaction-common-fields.html) are signed, except the signature itself. +- The key pair(s) used to sign the transaction are [authorized to send transactions on behalf of that account](transaction-basics.html#authorizing-transactions). +- The signature is _canonical_ and matches the transaction instructions. -Signatures created with the ECDSA algorithm and secp256k1 curve (the default) must also meet the following requirements: +Any change to the signed fields, no matter how small, would invalidate the signature, so no part of the transaction can be malleable except for the signature itself. In most cases, any change to a signature itself also invalidates the signature, but there are some specific exceptions, described below. + +### Alternate secp256k1 Signatures + +To be "canonical", signatures created with the ECDSA algorithm and secp256k1 curve (the default) must meet the following requirements: - The signature must be properly [DER-encoded data](https://en.wikipedia.org/wiki/X.690#DER_encoding). - The signature must not have any padding bytes outside the DER-encoded data. - The signature's component integers must not be negative, and they must not be larger than the secp256k1 modulus. -Generally speaking, any standard ECDSA implementation handles these requirements automatically. However, with secp256k1, those requirements are insufficient to prevent malleability. +Generally speaking, any standard ECDSA implementation handles these requirements automatically. However, with secp256k1, those requirements are insufficient to prevent malleability. Thus, the XRP Ledger has a concept of "fully canonical" signatures which do not have the same problem. -An ECDSA signature consists of two integers, called R and S. The secp256k1 modulus, called N, is a constant value for all secp256k1 signatures. Specifically, N is the value `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141`. For any given signature `(R,S)`, the signature `(R, N-S)` (that is, using N minus S in place of S) is also valid. Thus, to have _fully_ canonical signatures, one must choose which of the two possibilities is preferred and declare the other to be invalid. This is what the tfFullyCanonicalSig flag does: without that flag enabled, XRP Ledger transactions are valid with either of the two possible signatures; with it, the signature must use the _smaller_ of the two possible values, `S` or `N-S`. +An ECDSA signature consists of two integers, called R and S. The secp256k1 modulus, called N, is a constant value for all secp256k1 signatures. Specifically, N is the value `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141`. For any given signature `(R,S)`, the signature `(R, N-S)` (that is, using N minus S in place of S) is also valid. -To calculate a fully-canonical ECDSA signature, one must compare S and N-S +Thus, to have _fully_ canonical signatures, one must choose which of the two possibilities is preferred and declare the other to be invalid. The creators of the XRP Ledger decided arbitrarily to prefer the _smaller_ of the two possible values, `S` or `N-S`. A transaction is considered _fully canonical_ if it uses the preferred (smaller) value of `S`, and follows all the normal rules for being canonical. + +To maintain compatibility with older software that did not always generate fully canonical signatures, the XRP Ledger accepts transactions that are not fully canonical. To protect new users from exploits, the XRP Ledger has a flag on transactions called [**tfFullyCanonicalSig**](transaction-common-fields.html#global-flags), which requires that the transaction use a _fully-canonical_ signature to be valid. + +To calculate a fully-canonical ECDSA signature, one must compare S and N-S to determine which is smaller, then use that value in the `Signature` field of the transaction, and compute the identifying `hash` of the transaction using that version of the signature. + +All XRP Ledger software that Ripple publishes (including `rippled`, and ripple-lib/RippleAPI) generates only fully-canonical signatures. To further protect users, Ripple has configured its code to enable the **tfFullyCanonicalSig** flag by default where possible. Ripple strongly encourages third-party implementations of XRP Ledger software to generate only fully-canonical signatures, and enable tfFullyCanonicalSig on transactions by default. + + +### Malleability with Multi-Signatures + +An important, explicit feature of multi-signing is that multiple different possible configurations can render a transaction valid. For example, an account can be configured so that signatures from any three of five signers could authorize a transaction. However, this inherently means that there can be several different variations of a valid transaction, each with a different identifying hash. + +All of the following cases can lead to transaction malleability: + +- If a transaction still has enough signatures to meet its quorum after removing one or more. Any third party could remove a signature and calculate the hash of the modified transaction. +- If one can add a valid signature to a transaction that already has a quorum. Only one of the sending account's authorized signers could add such a signature. +- If one can replace one signature from a transaction with another valid signature while maintaining a quorum. Only one of the sending account's authorized signers could add such a signature. + +Generally, you can avoid problems when multi-signing if you do not collect more signatures than necessary and your authorized signers are not trying to exploit your software. Even if your authorized signers are not intentionally malicious, confusion or poor coordination could cause several signers to submit different valid versions of the same transaction. When using multi-signatures, you should be prepared for the possibility that transaction executes with a different hash and set of signatures than you expected. Carefully monitor your account's sent transactions (for example, using the [account_tx method][]) and do not automatically re-create multi-signed transactions. + + +## Exploit With Malleable Transactions + +If the software you use to interface with the XRP Ledger sends malleable transactions, a malicious actor may be able to trick your software into losing track of a transaction's final outcome and potentially (in the worst case) sending equivalent payments multiple times. + +If you use single-signatures and always enable the tfFullyCanonicalSig flag, you are not vulnerable to this exploit. If you use multi-signatures, you may be vulnerable if you or your signers provide more signatures than necessary. + +### Exploit Scenario Steps + +The process to exploit a vulnerable system follows a series of steps similar to the following: + +1. The vulnerable system constructs and signs a transaction without enabling tfFullyCanonicalSig. + + Three ways that a transaction may not enable the tfFullyCanonicalSig flag are: + + - The system explicitly specifies a `Flags` field that does not have the tfFullyCanonicalSig bit enabled. + - The transaction is multi-signed and does not explicitly enable the tfFullyCanonicalSig flag. + - The system omits the `Flags` field from the transaction fields, but uses a non-standard implementation that does not automatically enable tfFullyCanonicalSig when signing. + + To be vulnerable, the transaction must be signed with an ECDSA key pair. If multi-signed, the transaction must be signed by at least one ECDSA key pair. + + Most likely, the vulnerable transaction uses a fully-validated signature, but the flags indicate that the transaction would also be valid with a non-fully-canonical one. The transaction may also use `LastLedgerSequence` so that its final outcome is clear in a finite amount of time. + +2. The system notes the identifying hash of the vulnerable transaction, submits it to the XRP Ledger network, then begins monitoring for that hash to be included in a validated ledger version. + +3. A malicious actor sees the transaction propagating through the network before it becomes confirmed. + +4. The malicious actor calculates the alternate signature for the vulnerable transaction, and derives the hash of the resulting transaction data. + + Unlike creating a signature for a different transaction data, this does not require a large amount of computational work. It can be done in much less time than it takes to generate a signature in the first place. + +5. The malicious actor submits the modified (likely non-fully-canonical) transaction to the network. + + This creates a "race" between the transaction as originally submitted and the modified version submitted by the malicious actor. The two transactions are mutually exclusive. Both are valid, but they have the same exact transaction data, including the `Sequence` number, so at most one of them can ever be included in a validated ledger. + + Servers in the peer-to-peer network have no way of knowing which one "came first" or was intended by its original sender. Delays or other coincidences in network connectivity could result in validators seeing only one or the other by the time they finalize their consensus proposals, so either one could "win the race". + + A malicious actor could increase the chances of getting non-canonical transactions confirmed if they controlled some number of well-connected servers in the peer-to-peer network, even if those servers are not trusted as validators. + + If the malicious actor controls the only server to which the vulnerable system submitted the transaction, the malicious actor can easily control which version is distributed to the rest of the network. + +6. The malicious actor's version of the transaction achieves a consensus and becomes included in a validated ledger. + + At this point, the transaction has executed and cannot be reversed. Its effects (such as sending XRP) are final. The original version of the transaction is no longer valid because its `Sequence` number has been used. + + The effects of the transaction in the XRP Ledger are exactly the same as if the original version had executed. + +7. The vulnerable system does not see the transaction hash it is expecting, and erroneously concludes that the transaction did not execute. + + If the transaction included the `LastLedgerSequence` field, this would occur after the specified ledger index has passed. + + If the transaction omitted the `LastLedgerSequence` field, this could be wrong in another way: there is no amount of time after which you can definitively conclude that such a transaction could not later succeed. (See [Reliable Transaction Submission](reliable-transaction-submission.html) for details.) + +8. The vulnerable system takes action assuming that the transaction has failed. + + For example, it may refund (or simply not debit) a customer's balance in its own system, to account for the funds that it thinks have not been sent in the XRP Ledger. + + Worse, the vulnerable system might construct a new transaction to replace the transaction, picking new `Sequence`, `LastLedgerSequence`, and `Fee` parameters based on the current state of the network, but keeping the rest of the transaction the same as the original. If this new transaction is also malleable, the system could be exploited in the same way an indefinite number of times. + + +{% include '_snippets/rippled-api-links.md' %} +{% include '_snippets/tx-type-links.md' %} +{% include '_snippets/rippled_versions.md' %} From 43a06120e9407ab3f76f9951383e0a13ac828f8d Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Wed, 9 Jan 2019 17:11:42 -0800 Subject: [PATCH 3/7] Transaction malleability cleanup --- .../transaction-malleability.md | 27 +++++++++++++++---- dactyl-config.yml | 9 +++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/content/concepts/consensus-network/transaction-malleability.md b/content/concepts/consensus-network/transaction-malleability.md index 5d78985ac5..fa12c88f9f 100644 --- a/content/concepts/consensus-network/transaction-malleability.md +++ b/content/concepts/consensus-network/transaction-malleability.md @@ -45,6 +45,11 @@ To calculate a fully-canonical ECDSA signature, one must compare S and N-S to de All XRP Ledger software that Ripple publishes (including `rippled`, and ripple-lib/RippleAPI) generates only fully-canonical signatures. To further protect users, Ripple has configured its code to enable the **tfFullyCanonicalSig** flag by default where possible. Ripple strongly encourages third-party implementations of XRP Ledger software to generate only fully-canonical signatures, and enable tfFullyCanonicalSig on transactions by default. +There are two cases where Ripple's signing implementations for the XRP Ledger do not automatically enable the tfFullyCanonicalSig flag. Users should take care to set the flag in these situations: + +- When the user explicitly specifies the `Flags` field of the transaction. Use bitwise OR to apply tfFullyCanonicalSig _and_ any other desired flags. +- When the user provides a multi-signature for a transaction. Since different participants in a multi-signature must sign _exactly_ the same data, the signing code does not pre-process the transaction instructions to add the tfFullyCanonicalSig flag. For multi-signed transactions, always enable the tfFullyCanonicalSig flag explicitly. + ### Malleability with Multi-Signatures @@ -53,10 +58,21 @@ An important, explicit feature of multi-signing is that multiple different possi All of the following cases can lead to transaction malleability: - If a transaction still has enough signatures to meet its quorum after removing one or more. Any third party could remove a signature and calculate the hash of the modified transaction. -- If one can add a valid signature to a transaction that already has a quorum. Only one of the sending account's authorized signers could add such a signature. -- If one can replace one signature from a transaction with another valid signature while maintaining a quorum. Only one of the sending account's authorized signers could add such a signature. +- If one can add a valid signature to a transaction that already has a quorum. Only an authorized signer of the sending account could create such a signature. +- If one can replace one signature from a transaction with another valid signature while maintaining a quorum. Only an authorized signer of the sending account could create such a signature. -Generally, you can avoid problems when multi-signing if you do not collect more signatures than necessary and your authorized signers are not trying to exploit your software. Even if your authorized signers are not intentionally malicious, confusion or poor coordination could cause several signers to submit different valid versions of the same transaction. When using multi-signatures, you should be prepared for the possibility that transaction executes with a different hash and set of signatures than you expected. Carefully monitor your account's sent transactions (for example, using the [account_tx method][]) and do not automatically re-create multi-signed transactions. +Even if your authorized signers are not intentionally malicious, confusion or poor coordination could cause several signers to submit different valid versions of the same transaction. + +**Good operational security can protect against these problems.** Generally, you can avoid transaction malleability problems when multi-signing if you follow good operational security practices, including the following: + +- Do not collect more signatures than necessary. +- Either designate one party to assemble a transaction after collecting the necessary number of signatures, or designate a "chain" where signers pass the transaction instructions forward to be signed in a predefined order. +- Do not add unnecessary or untrusted signers to your multi-signing lists, even if the `weight` values associated with their keys are insufficient to authorize a transaction. +- Be prepared for the possibility that a transaction executes with a different hash and set of signatures than you expected. Carefully monitor your account's sent transactions (for example, using the [account_tx method][]). +- If you re-create transactions to be multi-signed, _do not_ change the `Sequence` number unless you have manually confirmed that the intended actions have not already executed. +- Confirm that the tfFullyCanonicalSig flag is enabled before signing. + +For greater security, these guidelines provide multiple layers of protection. ## Exploit With Malleable Transactions @@ -117,7 +133,8 @@ The process to exploit a vulnerable system follows a series of steps similar to Worse, the vulnerable system might construct a new transaction to replace the transaction, picking new `Sequence`, `LastLedgerSequence`, and `Fee` parameters based on the current state of the network, but keeping the rest of the transaction the same as the original. If this new transaction is also malleable, the system could be exploited in the same way an indefinite number of times. + -{% include '_snippets/rippled-api-links.md' %} -{% include '_snippets/tx-type-links.md' %} +{% include '_snippets/rippled-api-links.md' %} +{% include '_snippets/tx-type-links.md' %} {% include '_snippets/rippled_versions.md' %} diff --git a/dactyl-config.yml b/dactyl-config.yml index 1a82c9dcc4..0f2baa4a48 100644 --- a/dactyl-config.yml +++ b/dactyl-config.yml @@ -474,6 +474,15 @@ pages: targets: - local + - md: concepts/consensus-network/transaction-malleability.md + html: transaction-malleability.html + funnel: Docs + doc_type: Concepts + category: Consensus Network + blurb: Be aware of ways transactions could be changed have a different hash than expected. + targets: + - local + - md: concepts/consensus-network/amendments.md html: amendments.html funnel: Docs From 43a9720d1ae065211abbd9963b169fa1258c9867 Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Wed, 9 Jan 2019 17:17:38 -0800 Subject: [PATCH 4/7] Tx malleability: highlight multi-sign problem mitigations --- .../concepts/consensus-network/transaction-malleability.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/concepts/consensus-network/transaction-malleability.md b/content/concepts/consensus-network/transaction-malleability.md index fa12c88f9f..b062c8ce28 100644 --- a/content/concepts/consensus-network/transaction-malleability.md +++ b/content/concepts/consensus-network/transaction-malleability.md @@ -12,7 +12,7 @@ There are two circumstances that could lead to transaction malleability: 2. The transaction is [multi-signed](multi-signing.html) and has more signatures than necessary. Even if the transaction originally did not have more signatures than necessary, it could be malleable if one of the authorized signers provides an additional signature. - There is no solution that prevents all variations of this problem. When using multi-signatures, monitor your account for transactions sent even if they have different hashes, and try not to collect more signatures than necessary. + Good operational security can protect against these problems. See [Mitigations for Multi-Signature Malleability](#mitigations-for-multi-signature-malleability) for guidelines. ## Background @@ -63,6 +63,8 @@ All of the following cases can lead to transaction malleability: Even if your authorized signers are not intentionally malicious, confusion or poor coordination could cause several signers to submit different valid versions of the same transaction. +#### Mitigations for Multi-Signature Malleability + **Good operational security can protect against these problems.** Generally, you can avoid transaction malleability problems when multi-signing if you follow good operational security practices, including the following: - Do not collect more signatures than necessary. From 47b94cf37d9202e89911aeb140a1cd0e0bb86214 Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Wed, 9 Jan 2019 17:19:24 -0800 Subject: [PATCH 5/7] Tx malleability reword --- content/concepts/consensus-network/transaction-malleability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/concepts/consensus-network/transaction-malleability.md b/content/concepts/consensus-network/transaction-malleability.md index b062c8ce28..002897fb96 100644 --- a/content/concepts/consensus-network/transaction-malleability.md +++ b/content/concepts/consensus-network/transaction-malleability.md @@ -10,7 +10,7 @@ There are two circumstances that could lead to transaction malleability: **Use the [tfFullyCanonicalSig flag](transaction-common-fields.html#global-flags)** to guarantee that a transaction is not malleable in this way. Although transactions [signed with Ed25519 keys](cryptographic-keys.html#signing-algorithms) are not vulnerable to this problem, **there is no downside** to using this flag on _all_ transactions. -2. The transaction is [multi-signed](multi-signing.html) and has more signatures than necessary. Even if the transaction originally did not have more signatures than necessary, it could be malleable if one of the authorized signers provides an additional signature. +2. The transaction is [multi-signed](multi-signing.html) and has more signatures than necessary. Even if the transaction originally did not have more signatures than necessary, it could be malleable if an authorized signer provides an additional signature. Good operational security can protect against these problems. See [Mitigations for Multi-Signature Malleability](#mitigations-for-multi-signature-malleability) for guidelines. From 23e366c22038623b6fcced1fbc4591b82498764a Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Mon, 14 Jan 2019 13:28:01 -0800 Subject: [PATCH 6/7] Tx malleability: edits per reviews --- .../transaction-malleability.md | 19 ++++++++++++------- dactyl-config.yml | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/content/concepts/consensus-network/transaction-malleability.md b/content/concepts/consensus-network/transaction-malleability.md index 002897fb96..b99acb01e2 100644 --- a/content/concepts/consensus-network/transaction-malleability.md +++ b/content/concepts/consensus-network/transaction-malleability.md @@ -25,6 +25,8 @@ In the XRP Ledger, a transaction cannot execute unless: Any change to the signed fields, no matter how small, would invalidate the signature, so no part of the transaction can be malleable except for the signature itself. In most cases, any change to a signature itself also invalidates the signature, but there are some specific exceptions, described below. +Since the signature is among the data used to compute a transaction's identifying hash, any changes to a malleable transaction result in a different hash. + ### Alternate secp256k1 Signatures To be "canonical", signatures created with the ECDSA algorithm and secp256k1 curve (the default) must meet the following requirements: @@ -41,7 +43,7 @@ Thus, to have _fully_ canonical signatures, one must choose which of the two pos To maintain compatibility with older software that did not always generate fully canonical signatures, the XRP Ledger accepts transactions that are not fully canonical. To protect new users from exploits, the XRP Ledger has a flag on transactions called [**tfFullyCanonicalSig**](transaction-common-fields.html#global-flags), which requires that the transaction use a _fully-canonical_ signature to be valid. -To calculate a fully-canonical ECDSA signature, one must compare S and N-S to determine which is smaller, then use that value in the `Signature` field of the transaction, and compute the identifying `hash` of the transaction using that version of the signature. +To calculate a fully-canonical ECDSA signature, one must compare S and N-S to determine which is smaller, then use that value in the `Signature` field of the transaction. All XRP Ledger software that Ripple publishes (including `rippled`, and ripple-lib/RippleAPI) generates only fully-canonical signatures. To further protect users, Ripple has configured its code to enable the **tfFullyCanonicalSig** flag by default where possible. Ripple strongly encourages third-party implementations of XRP Ledger software to generate only fully-canonical signatures, and enable tfFullyCanonicalSig on transactions by default. @@ -57,7 +59,7 @@ An important, explicit feature of multi-signing is that multiple different possi All of the following cases can lead to transaction malleability: -- If a transaction still has enough signatures to meet its quorum after removing one or more. Any third party could remove a signature and calculate the hash of the modified transaction. +- If a transaction still has enough signatures to meet its quorum after removing one or more. Any third party could remove a signature and re-submit the transaction without it. - If one can add a valid signature to a transaction that already has a quorum. Only an authorized signer of the sending account could create such a signature. - If one can replace one signature from a transaction with another valid signature while maintaining a quorum. Only an authorized signer of the sending account could create such a signature. @@ -71,6 +73,7 @@ Even if your authorized signers are not intentionally malicious, confusion or po - Either designate one party to assemble a transaction after collecting the necessary number of signatures, or designate a "chain" where signers pass the transaction instructions forward to be signed in a predefined order. - Do not add unnecessary or untrusted signers to your multi-signing lists, even if the `weight` values associated with their keys are insufficient to authorize a transaction. - Be prepared for the possibility that a transaction executes with a different hash and set of signatures than you expected. Carefully monitor your account's sent transactions (for example, using the [account_tx method][]). +- Monitor the `Sequence` number of your account (for example, using the [account_info method][]). This number always increases by exactly one when your account sends a transaction successfully, and never any other way. If the number does not match what you expect, you should check your recent transactions to confirm why. (Aside from malleable transactions, there are other ways this could happen, too. Perhaps you configured another application to send transactions for you. Maybe a malicious user gained access to your secret key. Or perhaps your application lost data and forgot about a transaction you sent already.) - If you re-create transactions to be multi-signed, _do not_ change the `Sequence` number unless you have manually confirmed that the intended actions have not already executed. - Confirm that the tfFullyCanonicalSig flag is enabled before signing. @@ -97,15 +100,17 @@ The process to exploit a vulnerable system follows a series of steps similar to To be vulnerable, the transaction must be signed with an ECDSA key pair. If multi-signed, the transaction must be signed by at least one ECDSA key pair. - Most likely, the vulnerable transaction uses a fully-validated signature, but the flags indicate that the transaction would also be valid with a non-fully-canonical one. The transaction may also use `LastLedgerSequence` so that its final outcome is clear in a finite amount of time. + Most likely, the vulnerable transaction uses a fully-canonical signature, but the flags indicate that the transaction would also be valid with a non-fully-canonical one. The transaction may also use `LastLedgerSequence` so that its final outcome is clear in a finite amount of time. 2. The system notes the identifying hash of the vulnerable transaction, submits it to the XRP Ledger network, then begins monitoring for that hash to be included in a validated ledger version. 3. A malicious actor sees the transaction propagating through the network before it becomes confirmed. -4. The malicious actor calculates the alternate signature for the vulnerable transaction, and derives the hash of the resulting transaction data. +4. The malicious actor calculates the alternate signature for the vulnerable transaction. - Unlike creating a signature for a different transaction data, this does not require a large amount of computational work. It can be done in much less time than it takes to generate a signature in the first place. + Unlike creating a signature for different transaction instructions, this does not require a large amount of computational work. It can be done in much less time than it takes to generate a signature in the first place. + + The modified signature results in a different identifying hash. (You do not have to calculate the hash before you submit to the network, but knowing the hash makes it easier to check the transaction's status later.) 5. The malicious actor submits the modified (likely non-fully-canonical) transaction to the network. @@ -117,7 +122,7 @@ The process to exploit a vulnerable system follows a series of steps similar to If the malicious actor controls the only server to which the vulnerable system submitted the transaction, the malicious actor can easily control which version is distributed to the rest of the network. -6. The malicious actor's version of the transaction achieves a consensus and becomes included in a validated ledger. +6. The malicious actor's version of the transaction achieves consensus and becomes included in a validated ledger. At this point, the transaction has executed and cannot be reversed. Its effects (such as sending XRP) are final. The original version of the transaction is no longer valid because its `Sequence` number has been used. @@ -127,7 +132,7 @@ The process to exploit a vulnerable system follows a series of steps similar to If the transaction included the `LastLedgerSequence` field, this would occur after the specified ledger index has passed. - If the transaction omitted the `LastLedgerSequence` field, this could be wrong in another way: there is no amount of time after which you can definitively conclude that such a transaction could not later succeed. (See [Reliable Transaction Submission](reliable-transaction-submission.html) for details.) + If the transaction omitted the `LastLedgerSequence` field, this could be wrong in another way: if no other transaction from the same sender uses the same `Sequence` number, then the transaction could theoretically succeed later regardless of how much time has passed. (See [Reliable Transaction Submission](reliable-transaction-submission.html) for details.) 8. The vulnerable system takes action assuming that the transaction has failed. diff --git a/dactyl-config.yml b/dactyl-config.yml index 0f2baa4a48..128f28ad5f 100644 --- a/dactyl-config.yml +++ b/dactyl-config.yml @@ -479,7 +479,7 @@ pages: funnel: Docs doc_type: Concepts category: Consensus Network - blurb: Be aware of ways transactions could be changed have a different hash than expected. + blurb: Be aware of ways transactions could be changed to have a different hash than expected. targets: - local From 193f07640a8d5881cbcd752db4b3a4b22f13b994 Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Tue, 15 Jan 2019 15:46:41 -0800 Subject: [PATCH 7/7] Add Tx Malleability to recently updated --- dactyl-config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dactyl-config.yml b/dactyl-config.yml index 128f28ad5f..665aa029f3 100644 --- a/dactyl-config.yml +++ b/dactyl-config.yml @@ -45,6 +45,8 @@ targets: github_forkurl: https://github.com/ripple/ripple-dev-portal github_branch: master recently_updated: + - html: transaction-malleability.html + date: 2019-01-14 - html: ledger-history.html date: 2019-01-14 - html: online-deletion.html