Neo: Use consecutive tx.nonce, like counter

Created on 23 Mar 2020  路  14Comments  路  Source: neo-project/neo

Summary or problem description
In Neo3, we haven't used consecutive nonce, may lead to two problems:

  • Non-deterministic Transactions Order
    When sending multiple simultaneous transactions, a user cannot order their transactions in a
    deterministic way and this is important in many cases.

  • Replay Attack
    Due to the Nonce' lack of control an attacker can request a transaction from a user to do a payment, in a webstore for example, and carry out a Sybil Attack, restricting transaction broadcast over the network.
    The user when seeing that the payment has not been made (not included in a block), could repeat the payment (currently, generating a new random nonce).
    The attacker can capture all these transactions, even if the sum of them exceeds the balance of the user's wallet, and distribute them arbitrarily when the wallet has more balance. Subtracting more funds than the user initially wanted to send.

Do you have any solution you want to propose?

  • Implement a consecutive Nonce and store it on the blockchain, by address.
  • Wallets must also store the current Nonce, increasing security.
  • Only transactions with higher nonce than current one (without gaps) should be
    accepted.
  • The Memory Pool must accept transactions with the same nonce and update the
    pool with the transaction with more gas.
  • Check the behavior of ETH Transaction Nonce 2

Neo Version

  • Neo 3

Where in the software does this update applies to?

  • Transaction
  • Ledger
  • Wallets

_original posted by @red4sec_

discussion

Most helpful comment

  • With ValidUntilBlock you can't send a transaction with more gas in order to revert the previous one.
  • With ValidUntilBlock you can't ensure the order of Transactions. If we send A,B,C sometimes we need to ensure that the received order it's A,B,C.

Due to the Nonces' lack of control an attacker can request a transaction from a user to do a payment, in a webstore for example, and carry out a Sybil Attack, restricting transaction broadcast over the network.

The user when seeing that the payment has not been made (not included in a block), could repeat the payment (currently, generating a new random nonce).

The attacker can capture all these transactions, even if the sum of them exceeds the balance of the user's wallet, and distribute them arbitrarily when the wallet has more balance. Subtracting more funds than the user initially wanted to send.

image

All 14 comments

Non-deterministic Transactions Order
When sending multiple simultaneous transactions, a user cannot order their transactions in a
deterministic way

I think this is not a problem. Consecutive nonce will lead to other problems.

Consecutive nonce will lead to other problems.

It's true, and it may cause some synchronization problems.

But the good thing is, we have deterministic transaction order, and the possibility to cancel /speed up transaction.

If you want to cancel a transaction, you should use ValidUntilBlock.

I mean we have the possibility of canceling transactions that have not yet expired.

You can set ValidUntilBlock to a small value, such as 10 blocks.

  • With ValidUntilBlock you can't send a transaction with more gas in order to revert the previous one.
  • With ValidUntilBlock you can't ensure the order of Transactions. If we send A,B,C sometimes we need to ensure that the received order it's A,B,C.

Due to the Nonces' lack of control an attacker can request a transaction from a user to do a payment, in a webstore for example, and carry out a Sybil Attack, restricting transaction broadcast over the network.

The user when seeing that the payment has not been made (not included in a block), could repeat the payment (currently, generating a new random nonce).

The attacker can capture all these transactions, even if the sum of them exceeds the balance of the user's wallet, and distribute them arbitrarily when the wallet has more balance. Subtracting more funds than the user initially wanted to send.

image

If nonce it's only used for alter the hash of the tx, we can remove the nonce and fill the last script's opcodes with random values RETURN 0x0a0b0c

But our recomendation is to follow the nonce according to this page

https://github.com/ethereumbook/ethereumbook/blob/f85c5d334b33db9773c09b3f0fa3cd2994a7291a/06transactions.asciidoc#the-transaction-nonce

With ValidUntilBlock you can't send a transaction with more gas in order to revert the previous one.

NEO network generate block every 15 seconds, so I don't think that you have a chance to send another transaction with more gas to revert the previous one.

With ValidUntilBlock you can't ensure the order of Transactions. If we send A,B,C sometimes we need to ensure that the received order it's A,B,C.

I can't see a scenario.

The user when seeing that the payment has not been made (not included in a block), could repeat the payment (currently, generating a new random nonce).

You need to wait for the blocks exceeding the ValidUntilBlock to send another transaction. Then you are safe.

Non-deterministic Transactions Order

What if we're to add DependsOn attribute? It's almost like oracle request-response dependency, but completely controlled by the user, so if he cares about particular order he will set dependencies accordingly.

Replay Attack

What if we're to add ConflictsWith attribute that will explicitly declare that this transaction is invalid if the other one is already in the pool or chain?

And these are gonna be attributes, so completely optional and only used for particular problems.

If user has Solid States NEP on its wallet, this will never happen 馃槀
https://github.com/neo-project/proposals/issues/97

On Neo2 this is easily doable, but for Neo3, it makes transactions stateful again...
If we are to expand protection to assets, which is one of the most important applications, I still prefer some explicit operation, rather than nonce linking, that affects other things too.

24h's ValidUntilBlock increment might be still too long to prevent an attack. Unless we urge every one must not resend 24 hours after a "failed" transaction, but I doubt whether this is practical.

24h is a maximum value. You can also set 5 minutes.

24h is a maximum value. You can also set 5 minutes.

Should we enable setting this value in neo-node?

Was this page helpful?
0 / 5 - 0 ratings