-
Notifications
You must be signed in to change notification settings - Fork 0
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
Conditional compilation flag allows planting backdoor in ink! contracts #1
Comments
Thanks for reporting this issue!
It would be very unfortunate if we disallow conditional compilation flags altogether. What do you think about this mitigation instead:
This way users could still use conditional flags for e.g. only adding contract methods in a test environment. |
Other conditional compilation flags can be used with the same effect, with potentially more being added in the future to Rust. One example: How about having an allow-list of compilation flags? Including |
I've created use-ink/ink#2313 to fix the issue. Could you take a look? The failing CI there is because of an unrelated error, I'll fix that one in a separate PR. Two things:
|
Nice, the PR looks good to me, and the breaking change rationale too. |
Summary
When generating a contract's metadata, the ink! compiler parses the contract's code and takes into account conditional compilation flags. This allows malicious contract authors to hide messages, events and constructors from the metadata but place them in the WASM blob.
Issue details
ink! generates the code for metadata and embeds it inside the contract file, which, when compiled, outputs the metadata.
Due to the inclusion of conditional compilation flags such as
#[cfg(target_family="wasm")]
in metadata generation and the metadata not being compiled withwasm
, there can be a mismatch between the metadata and the compiledwasm
blob.Example Scenario
Suppose a malicious contract author adds a utility function
test_set_value
to their contract for use in tests, marked with#[cfg(any(test, target_family="wasm")]
. This message would allow any user to set the contract'svalue
to any integer, which they should not be able to do in a normal scenario.From the point of view of a contract's user, they would see this function used only in tests, but not be included in the metadata, even when they build it themselves on their machine.
A user would have to manually inspect the WASM blob to see the function included there. We argue that even advanced users are unlikely to manually inspect the WASM blob of the contract.
What we have in this situation is a backdoor planted by a malicious code author, hidden in the code through the seemingly test-only nature of the function, completely hidden from the metadata.
This malicious code author could at some point trigger this contract's message by manually calling its selector via the
contract-pallet
.Notice how the generated metadata does not list the message
test_set_value
. The function will nevertheless be compiled into the wasm blob and available through its selector like any other message.Risk
The discrepancy between a contract's WASM blob and the associated metadata allows an attacker to hide malicious functionality from a contract's users and exploit the contract after some desired outcome has been reached (e.g. some tokens have been deposited on the contract by victims).
Mitigation
The ink! toolchain should
Error
on all conditional compilation flags in a contract's source code.The text was updated successfully, but these errors were encountered: