A Tale of Three Thresholds: The Dangers of Low Threshold Operations
It was the best of times, it was the worst of times… it was Stellar times.
Operations on Stellar are grouped into one of three different security levels, called thresholds: Low, Medium, and High. When setting up a Stellar account to use multisig, you are given the option to set values for each of these threshold levels, as well as weights for each of the signers on the account. In order for a transaction to be considered valid, the weights of the signatures on the transaction that correspond to each operation’s source account must sum up to the value you set for the threshold for that operation type.
Whew, that’s a lot of words, but what does it really mean? Let’s look at an example.
Let’s say a Stellar account has the following threshold levels:
And the following signers and weights:
Master Weight: 2
Signer 1 Weight: 1
Signer 2 Weight: 1
That means that in order to perform a Medium threshold operation, like sending someone XLM, you must reach a total weight of 2, so either the account owner needs to sign the transaction or both Signers 1 and 2 need to sign it (so their combined weight equals 2).
For a High threshold transaction you’d need a combined weight of 3, so the account owner and one of the signers would need to sign it. Finally, a Low threshold operation only needs weight 1, so any of the signers on the account could sign in.
So now that we’ve gone over what thresholds are and how they work, let’s actually get to what this article is supposed to be about: what sort of trouble can you get yourself if you allow signers on your account to perform various thresholds of operations? Medium and High thresholds are obvious: anyone who has access to perform those operations can take all of your XLM or completely lock you out from your account. But what about low threshold operations?
Let’s say you’re setting up multisig like in one of the reference examples and you decide to leave the Low threshold as 0 like in an Anchor account. What sort of trouble can you get in if your secondary signature is leaked? Let’s look at the operations in the Low category and see:
Allow Trust — this lets the issuer of a custom asset allow other accounts to hold trustlines. So if AUTH_REQUIRED_FLAG or AUTH_REVOCABLE_FLAG is set, this could cause some disruptions like wiping out the order book for that asset. However none of it’s permanent and could all be put back to normal later.
So what if you aren’t an issuer of a custom asset, are there any risks?
Bump Sequence — this lets you bump your account’s sequence number forward to any number you choose. At first glance this doesn’t seem so bad: every transaction already consumes a sequence number, this just lets you pick the one you want. However the problem comes when you pick the maximum value allowed for this operation: 9223372036854775807. Once your account has this sequence number, it will be unable to be the source account for any further transactions, because its sequence number cannot go any higher and the transaction will be rejected. Now this seems bad, but not end-of-the-world bad: you can always use a different source account for your transactions that would use up its own sequence numbers instead. It would just be annoying to have to manage another set of accounts or keys, but you’d still be able to do transactions.
That’s all the operations, so we’re in the clear right? Even if a malicious actor was able to make low threshold operations on our account, we’d still be able to undo the damage in some way.
Not so fast. Low threshold operations also let you act as the source account for the entire transaction and pay the base fee for a transaction. This means that an attacker who can make low threshold transactions can slowly burn your account’s XLM by paying the tiny base fee that’s included with each operation! In practice this would take a long long time since the base fee is only 0.00001 XLM and there can only be 50 transactions every 5 seconds… so you’ll likely have a good amount of time to realize what’s happening and remove the offending signer.
Hold up. Not so fast I said! Turns out you can set your own base fee for a transaction, up to around 214 XLM, and you pay that fee for every single operation in the transaction (there can be 100 of them per transaction). That means in a single transaction you can burn 21400 XLM in fees. Do that 50 times to fill an entire ledger and you can burn about 1 million XLM every 5 seconds! Doesn’t seem so safe anymore, does it?
So if you ever find yourself configuring a Stellar account with weights and thresholds and think to yourself “hey, it could be convenient to set Low threshold to 0 so any one of my signers can Allow Trust”(I know this thought pops into my head every night), think long and hard on whether it’s worth the possibility of losing 1 million XLM every 5 seconds.