You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Dec 16, 2020. It is now read-only.
When manually inspecting block validation code, we noticed that the block validation logic is done in pieces, with a sqlite database as an intermediary. Or in other words, the logic for data validation and the logic for data persistence are commingled.
In particular, there is a "staging" sqlite database that appears to be a scratch space for blocks that haven't yet been incorporated into the main block store. The process_next_staging_block function is eventually called to process and (partially) validate aspects of a staged block:
However, note that in the implementation of that function, it is assumed that what is coming out of the staging database can be trusted, and that it's already been (partially) validated:
There are two downsides to this design (where data validation logic and data persistence logic are commingled):
It makes it difficult to reason about the correctness of the data validation logic.
It trusts what comes out of the persistence layer — though this may be unfounded! An attacker with access to the filesystem of an elected Blocks leader could modify data in between the time it is written to the persistence layer and the time when the Blocks node re-reads that data. This vector could be used, for example, to modify the contents of microblocks that the leader will commit to the blockchain. (Note that this seems like a high-difficulty, sophisticated attack.)
Our recommendation is that the block & transaction validation logic be cleanly separated from the data persistence logic, and that the validation logic is performed after data is retrieved from the persistence layer.
In short: do not trust what you're reading from the persistence layer to have integrity or authenticity; instead, verify those properties as data is retrieved.
The text was updated successfully, but these errors were encountered:
When manually inspecting block validation code, we noticed that the block validation logic is done in pieces, with a sqlite database as an intermediary. Or in other words, the logic for data validation and the logic for data persistence are commingled.
In particular, there is a "staging" sqlite database that appears to be a scratch space for blocks that haven't yet been incorporated into the main block store. The
process_next_staging_block
function is eventually called to process and (partially) validate aspects of a staged block:https://github.com/trailofbits/x-audit-blockstack-core/blob/e2d3d5bae539d242851620e28129af6c4a9de642/src/chainstate/stacks/db/blocks.rs#L2066-L2073
However, note that in the implementation of that function, it is assumed that what is coming out of the staging database can be trusted, and that it's already been (partially) validated:
https://github.com/trailofbits/x-audit-blockstack-core/blob/e2d3d5bae539d242851620e28129af6c4a9de642/src/chainstate/stacks/db/blocks.rs#L2142-L2144
There are two downsides to this design (where data validation logic and data persistence logic are commingled):
It makes it difficult to reason about the correctness of the data validation logic.
It trusts what comes out of the persistence layer — though this may be unfounded! An attacker with access to the filesystem of an elected Blocks leader could modify data in between the time it is written to the persistence layer and the time when the Blocks node re-reads that data. This vector could be used, for example, to modify the contents of microblocks that the leader will commit to the blockchain. (Note that this seems like a high-difficulty, sophisticated attack.)
Our recommendation is that the block & transaction validation logic be cleanly separated from the data persistence logic, and that the validation logic is performed after data is retrieved from the persistence layer.
In short: do not trust what you're reading from the persistence layer to have integrity or authenticity; instead, verify those properties as data is retrieved.
The text was updated successfully, but these errors were encountered: