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

Ensure absence of panics on scripts >4GB and other consensus-invalid data #59

Merged
merged 4 commits into from
Oct 31, 2023

Conversation

dr-orlovsky
Copy link
Member

@dr-orlovsky dr-orlovsky commented Oct 7, 2023

Bitcoin consensus encoding uses this idiotic thing named VarInt, which can have any value up to 64 bits and is used to encode length of all array data in consensus: number of transaction inputs, outputs, scripts, witnesses etc, etc. This is bad since none of these things in practice can have more than 2^16 items under the consensus rules - but still, an attacker can create a tx which contains octallions of elements in any of the consensus data...

This creates additional problems, since in RGB we'd like to ensure we can run a client-side-validation with clear restrictions on the memory, storage, bandwidth etc known beforehand - thus we have the strict type system and no collection of RGB data can have more than 64k elements or be larger than 16MB. But once we'd like to read Bitcoin tx from AluVM we instantly get into this trouble with octallions of bytes which may come from an attacker with the use of VarInt.

There are three ways of dealing with this situation:

  • not to care about it (like all Bitcoin wallets) and have an undefined behaviour under various forms of attacks, which one day may lead to global shutdowns like what happened to the lightning network because of the exact same issue;
  • assume that data must not be larger than a certain size and panic when they do, since it will indicate that they are not coming from Bitcoin consensus but from an attacker - this is what we do today, but it still allows an attacker to crash the software, which is not good;
  • still assume a size limit - but error and handle errors gracefully. This is the hardest way since it requires a lot of boilerplate code all around the place once we touch any data from Bitcoin - but I think this is inevitable.

This PR puts the foundations for such a thing into bp-consensus crate. Since it changes APIs (many functions will be returning Result now), it is an API-breaking change (but not RGB consensus-breaking) and has to go with a new v0.11 version

@dr-orlovsky dr-orlovsky added *security* Issues affecting safety/security (include undefined behaviours) epic Epic task refactoring Refactoring of the existing code labels Oct 7, 2023
@dr-orlovsky dr-orlovsky added this to the v0.11.0 milestone Oct 7, 2023
@dr-orlovsky dr-orlovsky force-pushed the master branch 2 times, most recently from 31b057c to d7fe526 Compare October 7, 2023 09:04
cryptoquick
cryptoquick previously approved these changes Oct 7, 2023
Copy link
Member

@cryptoquick cryptoquick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Graceful error handling is better than panics on UB. That way any future nodes might be able to handle attacks just by discarding things that don't parse according to Bitcoin consensus.

@dr-orlovsky
Copy link
Member Author

Now since we break APIs anyway with v0.11 I think it is time to merge this one as well. @zoedberg what do you think?

Copy link

codecov bot commented Oct 31, 2023

Codecov Report

Attention: 50 lines in your changes are missing coverage. Please review.

Files Coverage Δ
consensus/src/stl.rs 96.8% <ø> (ø)
src/stl.rs 100.0% <ø> (ø)
consensus/src/coding.rs 85.0% <0.0%> (+1.2%) ⬆️
consensus/src/taproot.rs 43.0% <0.0%> (-0.8%) ⬇️
consensus/src/segwit.rs 16.9% <8.3%> (-0.6%) ⬇️
consensus/src/script.rs 22.8% <3.1%> (-20.1%) ⬇️

📢 Thoughts on this report? Let us know!.

Copy link
Contributor

@zoedberg zoedberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now since we break APIs anyway with v0.11 I think it is time to merge this one as well. @zoedberg what do you think?

I agree

@dr-orlovsky dr-orlovsky merged commit e8273b7 into master Oct 31, 2023
17 of 18 checks passed
@dr-orlovsky dr-orlovsky deleted the script-varint branch November 14, 2023 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epic Epic task refactoring Refactoring of the existing code *security* Issues affecting safety/security (include undefined behaviours)
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants