Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime-sdk: potential DOS amplification: decrypt epoch #1051

Open
bennetyee opened this issue Jul 19, 2022 · 3 comments
Open

runtime-sdk: potential DOS amplification: decrypt epoch #1051

bennetyee opened this issue Jul 19, 2022 · 3 comments

Comments

@bennetyee
Copy link

the call format just tries to decrypt the wrapped call using the current epoch and previous epoch's key (in case epoch transition just occurred). this means that if the mempool is DOS'd, there are throughput issues, or some other reason exists where encrypted transactions are delayed for more than one epoch, those transactions will be rejected with Error::InvalidCallFormat. i think this also means that the transaction signer (EOA)'s nonce isn't incremented, so all subsequent transactions submitted -- assuming EOA nonce usage is the same as Ethereum's -- will have to wait until a replacement transaction with the now-missing nonce value is submitted. chances are that many/most users won't be able to react in time, and all the pending transaction proposals will become 2 or more epochs old and then fail in the same way.

i think ideally, the envelop will just include the epoch number as authenticated data, and retrying wouldn't be necessary.

we probably do want to have a limit on how far back in epoch numbers this can go, but it's a separate design/policy knob. if there were some performance hiccup that lasted too long, maybe cancelling all transactions from a user (or some users) is the right thing to do? (e.g. shedding load if there are throughput problems.) or, if we go the txn order finality route, the user made decisions based on their understanding of state, and virtual time line wise as long as txns aren't frontrunned or whatever, there's no reason for canceling?

and we'd be able to distinguish the case of bad data -- decryption failure -- and the epoch being too old, and have distinct error returns.

let (data, sk) = decrypt(ctx.epoch())
.or_else(|_| decrypt(ctx.epoch() - 1))

another (evil) thought: DOS'ing the mempool might be a more reliable way to cancel transactions than submitting a different transaction with the same nonce(s).

@bennetyee bennetyee changed the title potential DOS amplification: decrypt epoch runtime-sdk: potential DOS amplification: decrypt epoch Jul 19, 2022
@kostko
Copy link
Member

kostko commented Jul 19, 2022

i think this also means that the transaction signer (EOA)'s nonce isn't incremented

This is false as authentication and fee payment happens before decryption.

@kostko
Copy link
Member

kostko commented Jul 19, 2022

i think ideally, the envelop will just include the epoch number as authenticated data, and retrying wouldn't be necessary.

Yeah this is probably a better idea.

@bennetyee
Copy link
Author

This is false as authentication and fee payment happens before decryption.

ah. so the DOS opportunity would have to start w/ suppressing/delaying a proposal so the expected nonce is not seen at all, until its encryption key is from an epoch the number for which is 2+ current. subsequent proposals from the same EOA cannot be processed since they are out of sequence -- so they won't get to the decryption phase either. when the delayed proposal finally makes it into the mempool, then the EOA nonce / sequence number is incremented, and the decryption failure would occur w/ Error::InvalidCallFormat, and those other subsequent proposals can be processed, but whether they fail or not depends on whether they're also 2+ current epoch, independently of the delayed proposal. is this right?

this means that the amplification effect wrt failing transactions via decryption failures is much smaller, since they fail independently.

of course, this also means that an adversary can force a txn that they suspect will disadvantage them to fail while allowing through subsequent txns that may have been proposed assuming that the previous one would have succeeded actually do get committed, since in a non-confidential system there would not be a way to do that. proposers can defend against this, but we probably don't want to create a new attack vector -- i guess this line of thinking argues for no limits on how far back the encryption epoch might be, since this would close off all possibilities of the delay-proposal-to-block-txn attack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants