-
Notifications
You must be signed in to change notification settings - Fork 42
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
Vulnerability in VerifyNamespace: Partial Absence Proofs #110
Comments
cc: @liamsi @evan-forbes Please let me know your thoughts on this, thanks! |
Hmm, I fail to see if this actually causes any problems. But need to think about it further. The example you provided basically states that a root is sufficient to prove absence of a namespace (and is basically several instances of this case). In this case this is a subtree root but the base-case we should decide is: is it sufficient to provide only the root to prove that a namespace is not included?
Why is that? Don't the internal node equivalently prove the absence? If anything, the proof should consider the height as you suggested but I am not sure that is even necessary. Note that leaf and inner nodes are domain separated (like in rfc 6962) s.t. hashing a leaf and an inner node yields a different result. Though it sounds like in this specific questions/case is orthogonal to that. |
I think as long as this property really holds we are good either way. |
No. hash1 is // leafHash contains a tree leaf that 1) its namespace ID is the largest
// namespace ID less than nid and 2) the namespace ID of the leaf to the
// left of it is smaller than the nid 3) the namespace ID of the leaf to
// the right of it is larger than nid. Why is statement 2 necessary? If statement 1 is true, statement 2 must be true because the assumption that leaves of the NMT are sorted. |
@liamsi One reason that |
@rootulp Right, I recall that we discussed it for the NMT specification, the spec was updated, however, the code documentation was not updated accordingly at that time. Thank you for bringing this to my attention. Please see the following PR that addresses your concrn as well #114. |
@liamsi I want to clarify that I am not promoting this solution, but rather explaining how it can be implemented correctly. |
…proof (#114) ## Overview This PR intends to bring the description of the `leafHash` field in the `Proof `data structure in line with the specification. Additionally, among the three criteria enumerated for the `leafHash` the third criterion is redundant since it is already covered by the first two. Although this has already been addressed in the specification, the code description needs to be updated, and this PR accomplishes that (this comment was originally raised in #110 (comment)). ## Checklist - [x] New and updated code has appropriate documentation - [x] New and updated code has new and/or updated testing - [x] Required CI checks are passing - [x] Visual proof for any user facing features like CLI or documentation updates - [x] Linked issues closed with keywords
Yeah, I see. We need to fix this. Great find and write-up. Looking forward to the outcome of #118 |
Considering the results established in the following notion page we can consider this issue as completed. |
Problem
Identified as part of EPIC celestiaorg/celestia-app#1296.
The current implementation of
VerifyNamespace
is vulnerable to an issue in which a queried node can act inconsistently with the protocol specifications for when a queried namespace ID does not have corresponding items in the tree (i.e., absence proof). The attack/issue involves providing a partial absence proof for a namespace ID, while remaining undetected by the verification implementation. A partial proof in this case refers to a proof of an ancestor of a leaf to the root, rather than a proof of inclusion of the leaf to the tree. This is because the implementation cannot distinguish between a full or partial proof.Note: Please note that although
VerifyNamespace
is unable to detect partial proofs, the soundness of the namespace proof is not compromised. In other words, a malicious node is not able to convince someone of the absence of a namespace ID that actually exists in the tree. However, the inability to distinguish this inconsistent behavior may lead to incorrect conclusions being drawn at the application layer about the underlying data represented by NMT. The impact of this issue depends on the context in which NMT is being used and may or may not be considered an attack. Nevertheless, it is important to address this issue properly as it currently causes inconsistency and ambiguity in the verification process.Update: I suspect that the current implementation may be intentional to help with the non-interactive default rules for inclusion proofs of Blobs. Even if this is the case, the specs needs to be updated to make it clear whether partial absence proofs are considered valid or not.
Root Cause:
This is because
VerifyNamespace
does not consider the height of the tree or the total number of leaves during verification. Furthermore, the absence proof is based solely on the leaf hash and not on its underlying data. As a result, any internal node (non-leaf node) can be used as a leaf hash in the proof.Example:
Below is an example of such a partial proof that can be successfully verified by the
VerifyNamespace
algorithm.Description of the example: A correct absence proof for
nID=1
would consist of the following:proof.start=1
,proof.end=2
,proof.leafHash=leaf1
, andproof.nodes=[leaf0, hash2]
.However, it is possible to construct a partial proof that would also be considered correct by the
verifyNamespace
function.This alternate proof would have
proof.start=0
,proof.end=1
,proof.leafHash=hash1
, andproof.nodes=[hash2]
.Proposed Solutions
One of the following options will solve this issue:
VerifyNamespace
valid and include it in the specification.VerifyNamespace
by adding a new parameter to take the size of the tree, i.e., the number of data items it represents. This new parameter would be used to adjust the verification process to account for the tree size. By doing so, we can ensure that partial proofs do not comply with the height of the tree, since they will include fewer nodes than what is required for a full proof.The text was updated successfully, but these errors were encountered: