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

Detector for ecrecover return value validation and use of nonces #2015

Draft
wants to merge 15 commits into
base: dev
Choose a base branch
from

Conversation

tuturu-tech
Copy link

Used #1516 as a starting point, related to issue #1950

Detects the usage of ecrecover and checks if the signer address is validated against the zero address.
If a function uses ecrecover, checks if a nonce is present in any of the hashes.

Currently does so via string comparisons and naively checks any hash for a nonce, so it could have a lot of FPs

Comment on lines +132 to +138
if SolidityFunction("keccak256(bytes)") in node.solidity_calls:
for ir in node.irs:
if isinstance(ir, SolidityCall) and ir.function == SolidityFunction(
"keccak256(bytes)"
):
if "nonce" not in str(ir.expression):
nonce_results.append(node)
Copy link
Member

Choose a reason for hiding this comment

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

Some APIs will require that a hash is passed in and I think this would cause FPs. You may have to explore all paths starting from functions_entry_points and find the union of values not hashed but passed to ecrecover

Copy link
Member

Choose a reason for hiding this comment

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

Like this

def detect_msg_value_in_loop(contract: Contract) -> List[Node]:
results: List[Node] = []
for f in contract.functions_entry_points:
if f.is_implemented and f.payable:
msg_value_in_loop(f.entry_point, 0, [], results)
return results
def msg_value_in_loop(
node: Optional[Node], in_loop_counter: int, visited: List[Node], results: List[Node]
) -> None:
if node is None:
return
if node in visited:
return
# shared visited
visited.append(node)

Comment on lines +100 to +110
def _zero_address_validation(var: LocalVariable, function: Function) -> bool:
for node in function.nodes:
if node.contains_if() or node.contains_require_or_assert():
for ir in node.irs:
expression = str(ir.expression)
if isinstance(ir, Binary) and str(var) in expression:
if (
ir.type == BinaryType.NOT_EQUAL or ir.type == BinaryType.EQUAL
) and "address(0)" in expression:
return True
return False
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if it's helpful but there were some improvements desired in the missing-zero-check outlined in #1544 that may be relevant here

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

Successfully merging this pull request may close these issues.

None yet

3 participants