If I can get transaction info from the pending pool, does it mean it is a valid transaction?

Hi,

If I can get a transaction info from a transaction id with this REST API: GET /v2/transactions/pending/{txid} , does it mean this transaction in the pending pool is valid and will be for sure finalized in the blockchain eventually?

I am wondering that are all pending transactions in the pool valid ones? for example, is it possible that a transaction which is not properly signed can still go into the pool, such that even I can query its info with the above API, it is not valid and won’t be finalized in the chain?

Thank you,

To be more clear, my use case here is: I tell my customer that, if you claim you own account address A, create a transaction with 0 Algo and a random note string that I asked you to put (like “xyz”) then send to my account address B.

So the customer did this:

  1. He uses address A sent a transaction with 0 algo and note “xyz” to my address B, then he immediately sent me the transaction ID before the confirmation.

  2. With this transaction ID, I can immediately query the transaction info from the “Pending Pool” with function client.PendingTransactionInformation (in Golang) and verified that this transaction’s sender is A, receiver is B and note is “xyz”.

My question is, before this transaction gets confirmed in the blockchain, can I safely trust him that he own the account address A now? Apparently I can keep waiting until it gets confirmed, but that will need 5 more seconds. So I want to know that if I can get a transaction info from the “pending pool”, does it mean I can trust it is a valid / properly signed transaction and will be for sure finalized in the chain?

TL;DR: Do not rely on the pending pool for any security purposes. The pending pool access is meant to allow you checking your own transactions. It does not provide any security guarantee.

I see many ways the above can go wrong, even if signatures are checked before entering the pending pool (which may be the case right now but which is not at all guaranteed by the blockchain in the future).
Here are some.

A transaction in the transaction pool may not be finalized

For example, the block proposer for the next block sees the transactions in a different order (this can happen even if all the nodes are completely honest due to network delays), and the transaction you are checking is preceded by:

  • a rekey transaction of the account
  • a closing transaction of the account
  • or any other transaction that may invalidate the transaction.

This would invalidate your transaction.

An attacker can make you believe they control escrow accounts from applications

Currently a transaction will definitely be accepted in the transaction pool if its signature (i.e., ED25519 signature, multisig, or logic sig) is valid.
But a common pattern for escrow accounts (at least before AVM1.0) was to have the escrow account controlled by a smart signature that just requires the transaction to be called in a group of transactions where the first transaction call some smart contract application.
This is for example how the Yieldly escrow works.

Now, because the application in the group will check that you are allowed to do the operation, the actual transaction group would fail. But it would only fail when trying to finalize the transaction, not in the transaction pool!

More generally, logicsig/smart signatures may not check for the note field

Many logicsigs/smart signatures may just not check the note field when approving transaction, either because there is no security issue or because there is actually a need to allow an arbitrary note (this need most likely would come when used with a smart contract in a transaction group though).

Such smart signature accounts could also be claimed by an attacker.

Authentication is a very difficult topic in general

Using your method as a way to authenticate an account in general seems quite dangerous to me even if no smart contracts existed.
Here is an attack: suppose you wrote a dApp that requires users to authenticate their account.
What I can do as an attacker is to create another seamlessly safe dApp, for example for compounding rewards. I will ask my dApp users to sign in advance compounding transactions for the next year and then send the transactions for them.
This is a completely reasonable design and the user may trust me.
Now, the trick is that I can include your random note in this transaction.
Almost no users will realize this is dangerous when signing the transactions.

Actually, I can even justify the use of this random note: this is what goal does by default!

In other words, you cannot rely on the fact that a user is able to generate a correct transaction to show ownership of an account in a completely secure way.

To allow that securely, we need to design a secure standard that prevents this kind of man-in-the-middle attack. The kind of messages to be signed would be quite different (i.e., not transactions) and would include the origin of the request. (This is just a draft idea that requires a lot more investigation as secure authentication is an extremely complex subject.)

If you cannot wait for such a standard, you may require signature by the account of a special note that explicitly state that this is for your dApp and with a random value (at least 10-byte entropy).
You should manually verify this is a valid ED25519 signature or multisig.
You should systematically reject smart signatures.
You should check for potential rekeying on the blockchain.

3 Likes

wow, thank you for the answer @fabrice , it is very detailed and has a lot to digest for me, I really appreciate it! While I am not able to understand all of it now, I’ll keep learning, and oh, how much I love this community!

In other words, you cannot rely on the fact that a user is able to generate a correct transaction to show ownership of an account in a completely secure way.

I think this is the key take-away for me. So what is the correct way to enable user to sign in to a website with their wallet? Is the “Wallet Connect Protocol” the only way?