-
Notifications
You must be signed in to change notification settings - Fork 432
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
Custom Selectors and Proxy Selector Clashing Attacks #1643
Comments
Why are custom Proxy contracts needed? What extra features would each developer need to add to a Proxy contract? If there are only a few common Proxy patterns (multi-sig owner, upgrade voting, etc...), and they are published with audits. Then it should be easy to check for clashes between the Proxy and Impl. Auditing of a deployed contract that uses the Proxy pattern, should include both the Proxy and Implementation code/metadata. Removing custom selectors wouldn't fix the issue with possible clashing. Adding language support for Transparent proxy support, could make auditing easier. |
@ascjones, the description of the issue is fantastic. I have a couple of things I would like to add:
The solutions, in my opinion, can be these:
Malicious developers can create backdoors or honeypot functionalities to scam average users. The thing with custom selectors is that they enable the possibility to conceal the functionality in a way that is difficult to detect, even for experienced users. |
This might not cover possible clashing if the implementation is upgraded to a new version that adds new callable functions, unless the set of public callable functions is locked across all versions. If the implementation contract is not allowed to add new functions in newer versions, then the Proxy contract could be built using the first implementation version. In that case any clashing could give priority to the implementation over the Proxy's functions.
I meant what are the non-malicious use-cases for a custom Proxy. If there are only a few limited Proxy contract patterns, then those could be audited and any custom Proxy contract could have a big red warning on it (requiring extra auditing). |
BTW, I think ink! should support custom function path for selector(at least pin the prefix path). If you rename contract struct or move to new mod(it will happen when code line gets longer), the selector value will be changed. |
I have fleshed out this idea in |
We can remove wildcard selectors entirely, draft PR here: #1706. So for me it is a choice between
|
One big question we need to answer before moving forward with this, is do we want to support multi-faceted proxies as per https://eips.ethereum.org/EIPS/eip-1538? The single contract proxy is covered by |
The consultation period is over on this issue and we need to make a decision. To restate the choices are:
I am supporting #1708, on the grounds that:
|
Closed by #1708 |
I have opened #1634 to remove the custom selector functionality. Edit: now closed pending further decision.
As I understand it, the motivation for doing this is that it enables the following exploit when using the "proxy" contract pattern:
This is an instance of the "Proxy selector clashing" exploit raised first by Nomic and expanded upon in this OZ article: Beware of the proxy: learn how to exploit function clashing.
The main difference is that
ink!
allows custom selectors, whereas in Solidity they can only be derived from function names. The argument is that this makes the attack more likely to succeed because:It is objectively easier for the malicious contract author to craft a clashing malicious method with a custom selector, but would not be too difficult to do the same with function names:
As for whether a contract user reviewing the proxy contract is more or less likely to notice a malicious method with a clashing selector, that is entirely subjective. One could argue that someone familiar with
ink!
may notice the use of a custom selector in combination with a wildcard selector and immediately be suspicious, at least enough to read what the function is doing.So now we have to ask:
Applying the "precautionary principle" (remove it just in case), doesn't take into account the effect of unintended consequences e.g.:
Alternatives
Just a couple of ideas as alternatives to removing the feature entirely:
cargo-contract
or a block explorer e.g. https://etherscan.io/proxyContractCheckerproxy
, will only allow two methods: one with wildcard, one for upgrading the contract.The text was updated successfully, but these errors were encountered: