XRPL added a Batch execution feature. The idea was to have multiple instruction types, such as multiple payments, in a single transaction by batching them altogether. Right before launching the feature, the Cantina AI tool found a horrific vulnerability in the codebase. This is the bug report.
The inner transactions in a Batch are intentionally unsigned. This is because the authorization is delegated to the outer batch list of signers. Because of this, there's a function that checks that the owner of the transaction matches the signers. Otherwise, a batch could impersonate other users, so this check is crucial.
This validation could be bypassed in a single case: a signer whose account did not yet exist on the ledger and whose signing key matched their account would immediately return success without further validating the inner instructions. As a result, the validation of the remaining signers was completely skipped, allowing for impersonation of other users.
Here are the exploit steps:
- Attacker constructs a batch transaction with three inner instructions. One that creates a new account. One simple transaction from the new account with a valid signer. The final one is the exploit: a transaction where the attacker impersonates the victim.
- The attacker provides two batch signer entries: a legitimate one for account B and a forged one with the victim account.
- Because account B doesn't exist at validation time, the signer check exits successfully without validating the second.
- The victim's payment executes without the victim's key signing.
To remediate the issue, the batch proposal was rejected. The team is currently working on a fix for the vulnerability on the early exit. The bug was a funny edge case in the system. To me, this really shows that the more complex the system is, the more bugs like this will appear. Good job to the engineer and the Cantina AI for the discovery! We have entered a new era.